spring aop(九)--使用DefaultAdvisorAutoProxyCreator创建代理

来源:互联网 发布:pyqt linux 安装 arm 编辑:程序博客网 时间:2024/05/01 04:36
根据spring-framework-reference,DefaultAdvisorAutoProxyCreator创建代理更加通用强大,使用此机制包括:
a.指定一个DefaultAdvisorAutoProxyCreator Bean的定义.
b.指定在相同或相关的上下文中任意数量的Advisor.注意,必须是Advisor,而不仅仅是interceptor或advice.这是必要的,因为必须有一个切点被评估,以便检查每个advice到候选bean定义是否合格.
下面举个应用例子.

1.主要依赖(略)

2.具体类.

@Configurationpublic class AppConfig {//要创建代理的目标Bean@Beanpublic UserService userService(){return new UserServiceImpl();}//创建Advice@Beanpublic Advice myMethodInterceptor(){return new MyMethodInterceptor();}//使用Advice创建Advisor@Beanpublic NameMatchMethodPointcutAdvisor nameMatchMethodPointcutAdvisor(){NameMatchMethodPointcutAdvisor nameMatchMethodPointcutAdvisor=new NameMatchMethodPointcutAdvisor();nameMatchMethodPointcutAdvisor.setMappedName("pri*");nameMatchMethodPointcutAdvisor.setAdvice(myMethodInterceptor());return nameMatchMethodPointcutAdvisor;}@Beanpublic DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){return new DefaultAdvisorAutoProxyCreator();}}

public interface UserService {void print();}
public class UserServiceImpl implements UserService {public void print(){System.out.println(getClass()+"#print");}}
public class MyMethodInterceptor implements MethodInterceptor {@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {System.out.println(getClass()+"调用方法前");Object ret=invocation.proceed();System.out.println(getClass()+"调用方法后");return ret;}}

3.测试

public class Main {public static void main(String[] args) {ApplicationContext applicationContext=new AnnotationConfigApplicationContext(AppConfig.class);UserService userService= applicationContext.getBean(UserService.class);userService.print();}}
跟踪下实现:
和BeanNameAutoProxyCreator一样,DefaultAdvisorAutoProxyCreator也是一个BeanPostProcessor.它在Bean实例化随后,调用回调org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization进行后期处理来完成代理的创建.
其中AbstractAutoProxyCreator是BeanNameAutoProxyCreator的超类,BeanNameAutoProxyCreator没有重写postProcessAfterInitialization方法.下面看看这个方法:
看看wrapIfNecessary方法:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {if (beanName != null && this.targetSourcedBeans.contains(beanName)) {return bean;}if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {return bean;}if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {this.advisedBeans.put(cacheKey, Boolean.FALSE);return bean;}//这个bean是否匹配要创建代理也是在这个方法.Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);if (specificInterceptors != DO_NOT_PROXY) {this.advisedBeans.put(cacheKey, Boolean.TRUE);//关键代码在这里Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));this.proxyTypes.put(cacheKey, proxy.getClass());return proxy;}this.advisedBeans.put(cacheKey, Boolean.FALSE);return bean;}

先看看org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean方法(与BeanNameAutoProxyCreator不同),此处就可以找到在AppConfig配置的NameMatchMethodPointcutAdvisor.

@Overrideprotected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);if (advisors.isEmpty()) {return DO_NOT_PROXY;}return advisors.toArray();}
剩下的就与BeanNameAutoProxyCreator创建代理类似了.

0 0
原创粉丝点击