Federico Piazza
Federico Piazza

Reputation: 31045

Many instances of my aspect are being created outside spring container and properties aren't being injected

I have created an aspect to be launched on @AfterThrowing exception that has an @Autowired property.

I use the following code:

@Scope("singleton")
@Component
@Aspect
public class NotificationAspect
{
    @Autowired
    private EmailService emailService;

    private final Logger log = LoggerFactory.getLogger(NotificationAspect.class);

    public NotificationAspect()
    {
        log.info("****************** NotificationAspect: " + hashCode());
    }

    @AfterThrowing(pointcut="@annotation(com.creditsesame.integration.core.meta.NotifyOnFailures)",
                   throwing="ex")
    public void executeOnException(ApiExecutionException ex) throws Throwable
    {
        emailService.sendNotification();
    }
    // more code //
}

I put a breakpoint on the method executeOnException and confirmed that it is raising successfuly when an exception is thrown. The problem I have is that many instances not handled by spring are being created everytime the aspect is launched and since they aren't handled by spring all the autowired properties are null.

During the deployment when jboss starts the application I can see that initially the NotificationAspect contains its properties well injected. So, the issue on runtime and everytime the aspect is executed.

I have struggled a lot with this with no success. Any idea about how I can deal with this problem?

Thanks in advance.

Upvotes: 0

Views: 936

Answers (2)

Federico Piazza
Federico Piazza

Reputation: 31045

I could find the answer to make it work with xml approach since it was easier than using annotated beans (I had no luck to make it work with @Configurable).

I had to configure my aspect as:

<bean id="notificationAspect" factory-method="aspectOf" class="com.creditsesame.integration.core.aspect.NotificationAspect">
</bean>                          ^---Notice the factory-method with aspectOf()

On spring documentation says:

The majority of AspectJ aspects are singleton aspects. Configuration of these aspects is very easy: simply create a bean definition referencing the aspect type as normal, and include the bean attribute 'factory-method="aspectOf"'. This ensures that Spring obtains the aspect instance by asking AspectJ for it rather than trying to create an instance itself.

More information can be found on section 7.8.1 and 7.8.3 on below link:

http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/aop.html#aop-aj-ltw

Thanks Andrew Eisenberg for guide me on the right direction and Sotirios Delimanolis for provide some ideas.

Upvotes: 0

Andrew Eisenberg
Andrew Eisenberg

Reputation: 28757

At first, I was going to say that you cannot use dependency injection on an AspectJ aspect and that you must use spring aspects instead. However, I found this old post on Dependency injection with AspectJ and Spring. Basically, you need to tell the container to use the aspectOf() method as the factory-method. I have not tried this myself, but it looks like it might work. You will likely need to use xml to configure this.

Upvotes: 1

Related Questions