如何为 ProxyFactoryBean 设置多个目标?
how to set many targets to ProxyFactoryBean?
我正在使用 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 对象。
是否可以设置多个目标而不是一个?如果可能的话,我想将这些建议设置为整个包。否则,设定具体的目标,但又一次,不仅仅是一个。你怎么能做到这一点 ?提前致谢
您想要实现的目标可以通过在面向方面的语言中使用切入点来完成。因此,您可以定义切点以自动将方面应用于多个目标,例如实现相同的接口。查看更多详细信息here(滚动到 9.2.3 声明切点)。
使用 Spring 的 AutoProxy-Facility. Alas, the pointcut api is somewhat cumbersome to use in java based config; I usually subclass the AbstractAutoProxyCreator 最容易代理应用程序上下文中符合特定条件的所有 bean,因此我可以在 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,但要点应该可行。
最简单的方法是使用 AspectJ 注释 - 使用 within() 表达式
为此你需要
- 使用@Component 和@Aspect 注释创建"Aspect"Class
- 使用@Pointcut 注释在切面内创建 "Pointcut" 定义,
下面提到的例子
- 创建 "Advice" - Around,Before,AfterThrowing,AfterReturning 并提供
适当的建议实施
- 在您的设备上使用@EnableAspectJAutoProxy 启用AspectJ 配置
配置 class 和 'proxyTargetClass=true' 如果你想使用 CGLIB 代理
- 并确保你的方面 class 在扫描路径上
例如
@Pointcut(within(*..*Service))
public void allService(){}
上面的 within() 表达式将匹配所有以 'Service' 结尾的 class,您也可以匹配特定包中的所有 class。
我正在使用 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 对象。
是否可以设置多个目标而不是一个?如果可能的话,我想将这些建议设置为整个包。否则,设定具体的目标,但又一次,不仅仅是一个。你怎么能做到这一点 ?提前致谢
您想要实现的目标可以通过在面向方面的语言中使用切入点来完成。因此,您可以定义切点以自动将方面应用于多个目标,例如实现相同的接口。查看更多详细信息here(滚动到 9.2.3 声明切点)。
使用 Spring 的 AutoProxy-Facility. Alas, the pointcut api is somewhat cumbersome to use in java based config; I usually subclass the AbstractAutoProxyCreator 最容易代理应用程序上下文中符合特定条件的所有 bean,因此我可以在 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,但要点应该可行。
最简单的方法是使用 AspectJ 注释 - 使用 within() 表达式
为此你需要
- 使用@Component 和@Aspect 注释创建"Aspect"Class
- 使用@Pointcut 注释在切面内创建 "Pointcut" 定义, 下面提到的例子
- 创建 "Advice" - Around,Before,AfterThrowing,AfterReturning 并提供 适当的建议实施
- 在您的设备上使用@EnableAspectJAutoProxy 启用AspectJ 配置 配置 class 和 'proxyTargetClass=true' 如果你想使用 CGLIB 代理
- 并确保你的方面 class 在扫描路径上
例如
@Pointcut(within(*..*Service))
public void allService(){}
上面的 within() 表达式将匹配所有以 'Service' 结尾的 class,您也可以匹配特定包中的所有 class。