внедренные переменные экземпляра равны нулю при выполнении аспекта - PullRequest
2 голосов
/ 15 июня 2011

У меня странная проблема с 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");
            }
    }
}

Я получаю исключение NullPointerException в строке 4. Я вижу, что «фабрика» равна нулю в строке 3, но она не равна нулю, когда экземпляр создается в строке 2. Я также отслеживаю экземпляры, создаваемые в строке 1 .

Этот проект работает с использованием интерфейсов (динамические прокси JDK). Почему мои переменные экземпляров становятся нулевыми во время выполнения и есть ли обходной путь к этому?

1 Ответ

2 голосов
/ 15 июня 2011

Длинным и коротким является то, что вы не можете использовать инъекцию Spring на основе конструкторов с аспектами. На эту тему есть хорошее обсуждение на форуме здесь .

Я лично использую инъекцию, основанную на свойствах, для своих аспектов, как это было предложено на форуме выше. Приведенный ниже пример позволяет вам внедрить сервис в аспект аудита. Вам не нужны никакие дополнительные настройки XML, если ваш аспект реализует 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;       
 }
...