问题
I am working with Spring 4 AOP and right now, i have my ProxyFactoryBean configured like this:
@Bean
@Primary
public ProxyFactoryBean proxyFactoryBean() {
ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
proxyFactoryBean.setTarget(new ClientService());
proxyFactoryBean.addAdvice(new LoggingAdvice());
proxyFactoryBean.addAdvice(new DebugInterceptor());
return proxyFactoryBean;
}
This works, but the target is just the ClientService object.
Is it possible to set many targets and not just one ? I want to set those advices to an entire package, if it is possible. Otherwise, set specifics targets, but again, not just one. How could you do that ? Thanks in advance
回答1:
Proxying all beans in an application context that match certain criteria is easiest done with Spring's AutoProxy-Facility. Alas, the pointcut api is somewhat cumbersome to use in java based config; I usually subclass the AbstractAutoProxyCreator so I can express the pointcut in java code.
For instance, I'd do something like:
@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();
}
This code is untested, as I don't have an IDE with Spring (or Maven) at hand, but the gist should work.
回答2:
What you are trying to achieve can be done by using point-cuts in an aspect oriented language. So you can define point cut to automatically apply the aspect to multiple targets say implementing the same interface. See more details here (scroll to 9.2.3 Declaring a point cut).
回答3:
Easiest way to do this is with using AspectJ annotations - use within() expression
For this you will need to
- Create "Aspect" Class using @Component and @Aspect annotations
- Create "Pointcut" definition within the aspect using @Pointcut annotation, example is mentioned below
- Create "Advice" - Around,Before,AfterThrowing,AfterReturning and provide appropriate advice implementation
- Enable AspectJ configuration using @EnableAspectJAutoProxy on your configuration class with 'proxyTargetClass=true' if you want to use CGLIB proxy
- and make sure your aspect class is on the scan path
e.g.
@Pointcut(within(*..*Service))
public void allService(){}
above within() expression will match all classes ending with 'Service', you can also match all classes in a particular package as well.
来源:https://stackoverflow.com/questions/29375690/how-to-set-many-targets-to-proxyfactorybean