0
votes

I'm writing a plugin for an existing application and I need to add an "After returning" advice to the certain method. aspectj-autoproxy is currently disabled.

To avoid possible side effects for existing classes that have AspectJ annotations that are currently ignored I'd like to enable these annotations handling only for my bean. However, @EnableAspectJAutoProxy affects the entire context.

The only thing that comes to my mind is to manually construct the proxy using ProxyFactory, but after this I'll have two beans and I won't be able to use AspectJ expressions.

@Configuration
public class MyConf {
@Primary
@Bean
public SomeBean getSomeBean(@Autowired @Qualifier("SomeBeanImpl") target) {
    ProxyFactory factory = new ProxyFactory(target);
    // setup the advice, the method filter etc.
    return (SomeBean)factory.getProxy();
}

Is there some other set of annotations to create advices without globally enabling aspectj-autoproxy?

Upd

Looks like I need to dig towards manually registering another AnnotationAwareAspectJAutoProxyCreator instance with includePatterns property set.

1
That is what the pointcut expression is for. It will limit the affected beans.M. Deinum
@M.Deinum you musunderstood. It's about enabling some aspect beans, not enabling aspects for some beans. Updated the titlebasin
The EnableAspectJAutoproxy is the instruction to enable aspect processing and handling and works per context that is simply not changeable. which beans an aspect applies to is what a pointcut is for which you should use. Unless you manually configure each and every aspect (and manually create the aspect creation logic) but then again what is the point of writing a pointcut/aspect if you do that? Basically beats the purpose of it.M. Deinum

1 Answers

0
votes

Both @EnableAspectJAutoProxy and <aop:aspectj-autoproxy> enable creation of the bean post-processor singleton AnnotationAwareAspectJAutoProxyCreator. This object has an optional property includePatterns for filtering the eligible annotated aspect beans. By default all annotated aspect beans are eligible which means that advisors will be created for their annotated methods and these advisors will later be matched while wrapping the other beans with proxies.

includePatterns is only configurable via the XML tag <aop:include> , there's no annotation equivalent. If you have <aop:include> in one of your XML configs you can't clear includePatterns to make all annotated aspects eligible.

All this makes it pointless to use AspectJ annotations if you want to avoid side effects. To create just one aspect bean without enabling aspectj-autoproxy it's optimal to configure that bean with the <aop:config> tag:

<aop:config>
    <aop:aspect ref="aroundExample">
        <aop:after-returning method="afterDoSomething"
            pointcut="execution(* org.foo.Some.doSomething(..)) &amp;&amp; target(target) &amp;&amp; args(param,..)" 
            returning="retval"
            arg-names="target,retval,param"
            />
    </aop:aspect>
</aop:config>
<!--
This is disabled:
<aop:aspectj-autoproxy>
    <aop:include name="aroundExample"></aop:include>
</aop:aspectj-autoproxy>
-->

The annotations on the aspect bean are no longer needed:

@Component
// @Aspect
// @EnableAspectJAutoProxy -- yes, it wasn't necessary to place it on a @Configuration bean
@ImportResource("classpath:org/foo/aroundexample-config.xml")
public class AroundExample {

    // @AfterReturning(pointcut = "execution(* " + "org.foo.Some.doSomething"
    // + "(..)) && target(target) && args(param,..)", returning = "retval",
    // argNames = "target,retval,param")
    public void afterDoSomething(
            // JoinPoint jp,
            Some target, String retval, String param) throws Throwable {
        // jp.getThis();
        System.err.println("afterDoSomething: " + param + " " + retval);
    }

}