注入的实例变量在方面执行时为null

时间:2011-06-15 00:00:29

标签: java spring aspectj spring-aop

我对Spring AOP有这个奇怪的问题,我希望有人可以对它有所了解。

我正在使用CGLIB代理,当我执行以下方面时,我得到一个空指针:

@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(com.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");
            }
    }
}

我在第4行得到一个NullPointerException。我可以看到第3行的“factory”为null但是在第2行创建实例时它不为null。我还跟踪在第1行创建的实例。

此设计使用接口(JDK动态代理)。为什么我的实例变量在运行时变为null并且有解决方法吗?

1 个答案:

答案 0 :(得分:2)

长期和短期是你不能使用Spring的基于构造函数的注入Aspects。关于这个主题here有一个很好的论坛讨论。

我个人使用基于属性的注射为我的方面,如上述论坛所示。下面的示例允许您将服务注入审计方面。只要您使方面实现ApplicationContextAware,就不需要任何其他XML配置。

@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;       
 }