4

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?

4

0 回答 0