【问题标题】:how to set many targets to ProxyFactoryBean?如何为 ProxyFactoryBean 设置多个目标?
【发布时间】:2015-03-31 18:20:41
【问题描述】:

我正在使用 Spring 4 AOP,现在,我的 ProxyFactoryBean 配置如下:

@Bean
@Primary
public ProxyFactoryBean proxyFactoryBean() {
    ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
    proxyFactoryBean.setTarget(new ClientService());
    proxyFactoryBean.addAdvice(new LoggingAdvice());
    proxyFactoryBean.addAdvice(new DebugInterceptor());
    return proxyFactoryBean;
}

这可行,但目标只是 ClientService 对象。

是否可以设置多个目标而不仅仅是一个?如果可能的话,我想将这些建议设置为整个包。否则,设定具体目标,但同样,不仅仅是一个。你怎么能做到这一点 ?提前致谢

【问题讨论】:

    标签: java interceptor spring-aop spring-4 aspect


    【解决方案1】:

    使用 Spring 的AutoProxy-Facility 最容易在应用程序上下文中代理所有符合特定条件的 bean。唉,pointcut api 在基于 java 的配置中使用起来有些麻烦;我通常将 AbstractAutoProxyCreator 子类化,这样我就可以在 java 代码中表达切入点。

    例如,我会这样做:

    @Bean
    AbstractAutoProxyCreator autoProxyCreator() {
        return new AbstractAutoProxyCreator() {
            @Override 
            protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource customTargetSource) {
                if (BusinessService.class.isAssignableFrom(beanClass)) {
                    return new Object[] {loggingAdvice()};
                } else {
                    return DO_NOT_PROXY;
                }
            }
        };
    }
    
    @Bean
    LoggingAdvice loggingAdvice() {
        return new LoggingAdvice();
    }
    
    @Bean
    public PersonService personService() {
        return new PersonService();
    }
    

    此代码未经测试,因为我手头没有带有 Spring(或 Maven)的 IDE,但要点应该可以工作。

    【讨论】:

    • 谢谢!我会试试的
    • @jscherman;嗨,你能分享你的代码吗?
    • 嘿@fatemeakbari,我发布这个已经6年了,我没有代码了,对不起
    • 谢谢@jscherman,我的问题解决了
    【解决方案2】:

    您想要实现的目标可以通过在面向方面的语言中使用切入点来完成。因此,您可以定义切入点以自动将方面应用于多个目标,例如实现相同的接口。查看更多详情here(滚动至 9.2.3 声明切入点)。

    【讨论】:

      【解决方案3】:

      最简单的方法是使用 AspectJ 注释 - 使用 within() 表达式

      为此,您需要

      1. 使用@Component 和@Aspect 注释创建“Aspect”类
      2. 使用@Pointcut 注释在方面内创建“切入点”定义, 例子在下面提到
      3. 创建“建议”-Around、Before、AfterThrowing、AfterReturning 并提供 适当的建议实施
      4. 使用@EnableAspectJAutoProxy 启用 AspectJ 配置 如果您想使用 CGLIB 代理,请使用“proxyTargetClass=true”的配置类
      5. 并确保您的方面类在扫描路径上

      例如

      @Pointcut(within(*..*Service))
      public void allService(){}
      

      within() 表达式将匹配所有以“Service”结尾的类,您也可以匹配特定包中的所有类。

      【讨论】:

        猜你喜欢
        • 2023-04-07
        • 1970-01-01
        • 2016-03-23
        • 1970-01-01
        • 1970-01-01
        • 2022-12-06
        • 2013-05-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多