spring aop(八)--使用BeanNameAutoProxyCreator创建代理

来源:互联网 发布:银魂在日本的人气 知乎 编辑:程序博客网 时间:2024/05/22 02:01
BeanNameAutoProxyCreator是自动代理创建器的三种(BeanNameAutoProxyCreator,DefaultAdvisorAutoProxyCreator,AbstractAdvisorAutoProxyCreator)之一.它是根据拦截器和设置的Bean的名称表达式做匹配来创建代理.下面是个例子
1.主要依赖(略)

2.声明一个环绕通知(拦截器)

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 interface UserService {void print();}public class UserServiceImpl implements UserService {public void print(){System.out.println(getClass()+"#print");}}
4.配置
@Configurationpublic class AppConfig {//要创建代理的目标Bean@Beanpublic UserService userService(){return new UserServiceImpl();}//创建Advice或Advisor@Beanpublic Advice myMethodInterceptor(){return new MyMethodInterceptor();}//使用BeanNameAutoProxyCreator来创建代理@Beanpublic BeanNameAutoProxyCreator beanNameAutoProxyCreator(){BeanNameAutoProxyCreator beanNameAutoProxyCreator=new BeanNameAutoProxyCreator();//设置要创建代理的那些Bean的名字beanNameAutoProxyCreator.setBeanNames("userSer*");//设置拦截链名字(这些拦截器是有先后顺序的)beanNameAutoProxyCreator.setInterceptorNames("myMethodInterceptor");return beanNameAutoProxyCreator;}}
5.测试
public class Main {public static void main(String[] args) {ApplicationContext applicationContext=new AnnotationConfigApplicationContext(AppConfig.class);UserService userService= applicationContext.getBean(UserService.class);userService.print();}}


跟踪下实现:
BeanNameAutoProxyCreator是一个BeanPostProcessor.它在Bean实例化随后,调用回调org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization进行后期处理来完成代理的创建.
其中AbstractAutoProxyCreator是BeanNameAutoProxyCreator的超类,BeanNameAutoProxyCreator没有重写postProcessAfterInitialization方法.下面看看这个方法:

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (bean != null) {Object cacheKey = getCacheKey(bean.getClass(), beanName);if (!this.earlyProxyReferences.contains(cacheKey)) {//关键代码在这里return wrapIfNecessary(bean, beanName, cacheKey);}}return bean;}
再看看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;}
再看看createProxy方法:
protected Object createProxy(Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {ProxyFactory proxyFactory = new ProxyFactory();proxyFactory.copyFrom(this);if (!proxyFactory.isProxyTargetClass()) {if (shouldProxyTargetClass(beanClass, beanName)) {proxyFactory.setProxyTargetClass(true);}else {evaluateProxyInterfaces(beanClass, proxyFactory);}}Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);for (Advisor advisor : advisors) {proxyFactory.addAdvisor(advisor);}proxyFactory.setTargetSource(targetSource);customizeProxyFactory(proxyFactory);proxyFactory.setFrozen(this.freezeProxy);if (advisorsPreFiltered()) {proxyFactory.setPreFiltered(true);}//关键代码看这里return proxyFactory.getProxy(getProxyClassLoader());}
再看看org.springframework.aop.framework.ProxyFactory#getProxy(java.lang.ClassLoader)如下:
public Object getProxy(ClassLoader classLoader) {return createAopProxy().getProxy(classLoader);}

再看看org.springframework.aop.framework.ProxyCreatorSupport#createAopProxy

public Object getProxy(ClassLoader classLoader) {return createAopProxy().getProxy(classLoader);}

再看看createAopProxy方法

protected final synchronized AopProxy createAopProxy() {if (!this.active) {activate();}return getAopProxyFactory().createAopProxy(this);}

剩下的就与ProxyFactoryBean创建代理类似了.

0 0
原创粉丝点击