开发者

injected instance variables are null on aspect execution

I have this odd problem with Spring AOP and I am hoping someone can shed some light on it.

I am using CGLIB proxies and when I execute the following aspect i get a null pointer:

@Aspect
@Component //i.e. Singleton
public class MyAspect {

    private static final Logger logger = LoggerFactory.getLogger(MyAspect.class);

    {

        logger.debug("new instance of MyAspect");  //Line 1
    }

    private AutowireCapableBeanFactory factory;

    @Inject
    public MyAspect(AutowireCapableBeanFactory factory) {

        if (factory ==null) {

            logger.debug("your factory is null");  //Line 2
        } else {

            logger.debug("your factory is not null");
        }
        this.factory = factory;
    }

    @AfterReturning(pointcut = "@annotation(co开发者_JAVA技巧m.domain.annotations.MyAnnotation)")
    public void doSomething() {

        if (factory ==null) {

            logger.debug("your factory is null again");  //Line 3
        }

                    // this is a request scoped bean
        MyRequest request = factory.getBean(MyRequest.class);  //Line 4



        if (request != null) {
            logger.debug("No");
            }
        else {
            logger.debug("Yes");
            }
    }
}

I am getting a NullPointerException at Line 4. I can see that the "factory" is null at Line 3 but it is not null when the instance is create at Line 2. I am also tracking the instances being created at Line 1.

This design works using interfaces (JDK dynamic proxies). Why do my instances variables become null at runtime and is there a work around to this?


Long and short is that you can't use Spring's constructer based injection with Aspects. There's a good forum discussion on this topic here.

I personally use property-based injection for my aspects as suggested in the above forum. The example below allows you to inject a service into an auditing aspect. You don't need any additional XML configuration, as long as you make your aspect implement ApplicationContextAware.

@Aspect
@Component("auditAspect")
public class AuditAspect implements ApplicationContextAware {

ApplicationContext context;

public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
    // do stuff with context here
}

public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;       
 }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜