spring 仅为某些方面 bean 启用 aspectj-autoproxy

spring enable aspectj-autoproxy only for some aspect beans

我正在为现有应用程序编写插件,我需要向特定方法添加“返回后”通知。 aspectj-autoproxy 当前已禁用。

为了避免现有 类 具有当前被忽略的 AspectJ 注释的可能的副作用,我想仅为我的 bean 启用这些注释处理。但是,@EnableAspectJAutoProxy 会影响整个上下文。

我唯一想到的是使用 ProxyFactory 手动构建代理,但在这之后我将有两个 bean,我将无法使用 AspectJ 表达式。

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

是否有一些其他注释集可以在不全局启用 aspectj-autoproxy 的情况下创建建议​​?

更新

看来我需要深入研究手动注册另一个 AnnotationAwareAspectJAutoProxyCreator 实例并设置 includePatterns 属性。

@EnableAspectJAutoProxy<aop:aspectj-autoproxy> 都可以创建 bean post-处理器单例 AnnotationAwareAspectJAutoProxyCreator。该对象有一个可选的 属性 includePatterns 用于过滤符合条件的注释方面 bean。默认情况下,所有带注释的方面 bean 都是合格的,这意味着将为它们带注释的方法创建顾问,并且这些顾问稍后将在用代理包装其他 bean 时进行匹配。

includePatterns 只能通过 XML 标签配置 <aop:include> ,没有等效的注解。如果您的 XML 配置之一中有 <aop:include>,您无法清除 includePatterns 以使所有带注释的方面都符合条件。

如果您想避免副作用,所有这些都使使用 AspectJ 注释毫无意义。要在不启用 aspectj-autoproxy 的情况下仅创建一个方面 bean,最好使用 <aop:config> 标记配置该 bean:

<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>
-->

不再需要方面 bean 上的注释:

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

}