SpringAOP源码解析之代理创建篇
2017-12-30 18:23
661 查看
阅读须知
Spring源码版本:4.3.8注释规则:
//单行注释做普通注释
/**/多行注释做深入分析
建议配合Spring源码阅读
正文
承接上文,在获取了所有bean匹配的增强器之后,就可以创建代理了:AbstractAutoProxyCreator:
protected Object createProxy( Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) { if (this.beanFactory instanceof ConfigurableListableBeanFactory) { AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass); } ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.copyFrom(this); //复制当前对象的相关属性 if (!proxyFactory.isProxyTargetClass()) { if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); //proxy-target-class配置 } 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()); }
ProxyFactory:
public Object getProxy(ClassLoader classLoader) { /*创建aop代理并获取代理对象*/ return createAopProxy().getProxy(classLoader); }
ProxyCreatorSupport:
protected final synchronized AopProxy createAopProxy() { if (!this.active) { activate(); } /*创建aop代理*/ return getAopProxyFactory().createAopProxy(this); }
DefaultAopProxyFactory:
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { //判断使用哪种代理 if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { Class<?> targetClass = config.getTargetClass(); if (targetClass == null) { throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); } }
这里我们看到了Spring如何选择使用JDK动态代理还是CGLIB代理,optimize用来控制通过CGLIB创建的代理是否使用激进的优化策略,这个配置对JDK动态代理无效,不推荐使用,proxy-target-class文章开始已经介绍过,逻辑就是在这里实现的,hasNoUserSuppliedProxyInterfaces判断目标类是否没有用户自定义的代理接口。我们先看JDK动态代理的方式:
JdkDynamicAopProxy:
public Object getProxy(ClassLoader classLoader) { if (logger.isDebugEnabled()) { logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource()); } /*是代理的接口完整*/ Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true); findDefinedEqualsAndHashCodeMethods(proxiedInterfaces); /*创建代理*/ return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); }
AopProxyUtils:
static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised, boolean decoratingProxy) { Class<?>[] specifiedInterfaces = advised.getProxiedInterfaces(); if (specifiedInterfaces.length == 0) { Class<?> targetClass = advised.getTargetClass(); if (targetClass != null) { if (targetClass.isInterface()) { advised.setInterfaces(targetClass); } else if (Proxy.isProxyClass(targetClass)) { advised.setInterfaces(targetClass.getInterfaces()); } specifiedInterfaces = advised.getProxiedInterfaces(); } } boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class); boolean addAdvised = !advised.isOpaque() && !advised.isInterfaceProxied(Advised.class); boolean addDecoratingProxy = (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class)); int nonUserIfcCount = 0; if (addSpringProxy) { nonUserIfcCount++; } if (addAdvised) { nonUserIfcCount++; } if (addDecoratingProxy) { nonUserIfcCount++; } Class<?>[] proxiedInterfaces = new Class<?>[specifiedInterfaces.length + nonUserIfcCount]; System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 0, specifiedInterfaces.length); int index = specifiedInterfaces.length; if (addSpringProxy) { proxiedInterfaces[index] = SpringProxy.class; index++; } if (addAdvised) { proxiedInterfaces[index] = Advised.class; index++; } if (addDecoratingProxy) { proxiedInterfaces[index] = DecoratingProxy.class; } return proxiedInterfaces; }
这里我们看到为即将创建的代理类添加了3个接口SpringProxy、Advised和DecoratingProxy,后面执行的过程中会用到。代理对象的创建到这里就结束了,我们会在下篇文章中继续分析AOP执行过程的源码。
相关文章推荐
- spring 源码探索 -- aop 标签解析和创建代理
- Spring AOP 源码分析 - 创建代理对象
- 【Spring源码--AOP的实现】(一)AopProxy代理对象的创建
- Spring源码之创建AOP代理(补)
- Spring源码阅读4.2-Aspecjt AOP之代理对象的创建
- Spring 源码分析(三) —— AOP(五)创建代理
- Spring AOP源码解析——AOP动态代理原理和实现方式
- Spring AOP高级——源码实现(3)AopProxy代理对象之JDK动态代理的创建过程
- Spring AOP 源码分析——创建代理对象
- SPRING源码学习之路(三)——<aop:config>自动代理的实现
- 【spring源码学习】spring的AOP面向切面编程的实现解析
- spring-aop源码解析:declare-parent
- Spring源码情操陶冶-AOP之Advice通知类解析与使用
- mybatis+spring源码解析(动态代理 spring初始化)
- spring 核心与源码解析(3):AOP如何使用
- Spring IoC源码解析——Bean的创建和初始化
- Spring源码分析:AOP源码解析(上篇)
- spring 代理对象方法增强源码解析
- Spring基于注解形式的 AOP的原理流程及源码解析(二)
- spring源码-5-aop动态代理