In my Spring web application, I'm trying to inject a resource in a perthis-scoped AspectJ aspect. Injection works well using a singleton aspect, but fails using a perthis scoped one. I tried using both @Autowire
annotation or xml <property>
tag.
Here is my code.
Aspect (for @Configurable I tried both autowire=Autowire.BY_TYPE
and autowire=Autowire.BY_NAME
):
@Aspect(
"perthis(org.mypackage.aop.aspects.TestAspect.participateAroundPointcut())")
@Component
@Scope("prototype")
@Configurable()
public class TestAspect {
private static final Logger logger = LoggerFactory.getLogger(TestAspect.class);
@Autowired
private CommonService commonService;
@Pointcut("execution(* org.mypackage.TestService.method(..))")
public void participateAroundPointcut(){}
@Around("participateAroundPointcut()")
public void testAround(ProceedingJoinPoint joinPoint) throws Throwable{
logger.debug("Pre-execution; commonService==null: "+(commonService==null)+";");
joinPoint.proceed();
logger.debug("Post-execution");
}
}
CommonService:
@Service
@Scope("request")
public class CommonService {
private String value = "commonValue";
}
and beans' xml configuration:
<context:component-scan base-package="org.mypackage" />
<aop:aspectj-autoproxy proxy-target-class="true"/>
<context:spring-configured />
<bean id="testAspect" class="org.mypackage.aop.aspects.TestAspect" scope="prototype" factory-method="aspectOf"/>
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />
And output confirming that commonService is not autowired:
DEBUG: org.mypackage.aop.aspects.TestAspect - Pre-execution; commonService==null: true;
DEBUG: org.mypackage.TestService - Executing method
DEBUG: org.mypackage.aop.aspects.TestAspect - Post-execution
Some configuration/annotation may be overloaded (for example i'm using both @Scope("prototype")
and scope="prototype"
in xml), because I tried all the possibilities.
However, setting singleton scope and removing perthis (and making CommonService singleton-scoped too) the field is correctly autowired.
Any help would be appreciated.
EDIT:
Removing scope="prototype"
from TestAspect xml bean definition I get the following exception:
java.lang.IllegalArgumentException: Bean with name 'testAspect' is a singleton, but aspect instantiation model is not singleton
at org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder.buildAspectJAdvisors(BeanFactoryAspectJAdvisorsBuilder.java:121)
at org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors(AnnotationAwareAspectJAutoProxyCreator.java:86)
at org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator.shouldSkip(AspectJAwareAdvisorAutoProxyCreator.java:107)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessBeforeInstantiation(AbstractAutoProxyCreator.java:275)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation(AbstractAutowireCapableBeanFactory.java:894)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation(AbstractAutowireCapableBeanFactory.java:866)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:451)
Although TestAspect class is annotated with @Scope("protptype")
, the bean is recognized like a singleton, causing the error. It seems that the container doesn't take into account the @Scope annotation, while it works for all other beans. Maybe @Configurable
isn't detected too, causing the autowiring error?