org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator
该类中做了对目标类的代理处理。

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupportimplements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware

继承ProxyProcessorSupport类
实现了SmartInstantiationAwareBeanPostProcessor接口,这里面有很多和bean实例化的生命周期相关的方法。
实现了BeanFactoryAware接口,设置BeanFactory的。


方法

由于有很多方法,对应不同的处理逻辑,暂时不分析其他的功能,只对自动代理的部分进行介绍

自动代理发生的地方是:postProcessAfterInitialization方法。在初始化完成之后


 @Overridepublic Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {if (bean != null) {Object cacheKey = getCacheKey(bean.getClass(), beanName);if (this.earlyProxyReferences.remove(cacheKey) != bean) {return wrapIfNecessary(bean, beanName, cacheKey);}}return bean;}
 protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {return bean;}// 如果不需要代理,直接返回这个beanif (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {return bean;}// 如果这个类是底层结构的类型,Advice,Pointcut,Advisor,AopInfrastructureBean// 这些代理的类是不能再次代理的// beanname是以ORIGINAL结尾的,或者@aspect注解标注的都需要跳过。if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {this.advisedBeans.put(cacheKey, Boolean.FALSE);return bean;}// 找到和这个类匹配的切面,虽然返回的是Object类型,但确定是切面类型// 这个是子类实现的。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;}// 如果没有拦截器的信息,返回的是bean实例this.advisedBeans.put(cacheKey, Boolean.FALSE);return bean;}

查看bean是否是不能被代理的,如果不符合条件,返回的是bean实例
如果可以代理,查看是否有针对这个类的拦截器,如果有,创建代理。没有的话返回bean实例


下面看下是如何创建代理的
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy

 protected Object createProxy(Class<?> beanClass, @Nullable String beanName,@Nullable Object[] specificInterceptors, TargetSource targetSource) {// 设置这个bean的bd中的属性,该bean类型是一个特殊的bean类型if (this.beanFactory instanceof ConfigurableListableBeanFactory) {AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);}// 一个对象使用一个ProxyFactory,所以可以根据对象的需要自定义值ProxyFactory proxyFactory = new ProxyFactory();// 这里是将代理的属性信息传给ProxyFactoryproxyFactory.copyFrom(this);// 如果是类代理,则直接到下一步了,// 如果是接口代理,还需要判断下:// 这个代理类型的设置是全局设置的,如果不想使用全局的,可以设置自己的代理方式。if (!proxyFactory.isProxyTargetClass()) {// 判断是否bean自定义了代理方式,要使用类代理。if (shouldProxyTargetClass(beanClass, beanName)) {proxyFactory.setProxyTargetClass(true);}// 如果没有,则将解析出这个类的所有接口放入proxyFactoryelse {evaluateProxyInterfaces(beanClass, proxyFactory);}}// 得到所有的切面类Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);proxyFactory.addAdvisors(advisors);proxyFactory.setTargetSource(targetSource);customizeProxyFactory(proxyFactory);proxyFactory.setFrozen(this.freezeProxy);if (advisorsPreFiltered()) {proxyFactory.setPreFiltered(true);}return proxyFactory.getProxy(getProxyClassLoader());}

每个bean都有一个代理工厂类;
bean可以自定义代理的方式。


org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#buildAdvisors

 protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {// 除了spring自动给找的切面类,创建beanpostPorcessor时,还可以添加自己的切面// 这个方法就是解析自己添加的的切面。Advisor[] commonInterceptors = resolveInterceptorNames();List<Object> allInterceptors = new ArrayList<>();if (specificInterceptors != null) {allInterceptors.addAll(Arrays.asList(specificInterceptors));if (commonInterceptors.length > 0) {// 如果应用公共拦截器的话,就把公共的拦截器放在最开始,// 如果不应用的话,放在最后if (this.applyCommonInterceptorsFirst) {allInterceptors.addAll(0, Arrays.asList(commonInterceptors));}else {allInterceptors.addAll(Arrays.asList(commonInterceptors));}}}if (logger.isTraceEnabled()) {int nrOfCommonInterceptors = commonInterceptors.length;int nrOfSpecificInterceptors = (specificInterceptors != null ? specificInterceptors.length : 0);logger.trace("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors +" common interceptors and " + nrOfSpecificInterceptors + " specific interceptors");}// Advisor[] advisors = new Advisor[allInterceptors.size()];for (int i = 0; i < allInterceptors.size(); i++) {// 包装成切面类advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));}return advisors;}

将spring容器的切面类和自己的切面类整合。

proxyFactory创建代理

看一下代理工厂的继承关系

public class ProxyFactory extends ProxyCreatorSupport {public class ProxyCreatorSupport extends AdvisedSupport {public class AdvisedSupport extends ProxyConfig implements Advised {

ProxyConfig 之前已经介绍了,保存了代理的信息;
AdvisedSupport 主要是保存被代理类的信息;如果说给哪个对象代理?这个被代理类用哪些能应用的切面。最重要的是有一个功能,可以将切面类中的增强转化为拦截器类:这个稍后j将。
ProxyCreatorSupport 则是创建代理;
ProxyFactory 类似一个整合。

代理的创建

 // config对象是代理工厂自身public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {// 是否是类代理:ObjenesisCglibAopProxyif (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);}// 不是类代理JdkDynamicAopProxyelse {return new JdkDynamicAopProxy(config);}}

参数已经是config,也就是代理工厂,这个有所有的参数,代理对象,切面等信息。

 public Object getProxy(@Nullable ClassLoader classLoader) {if (logger.isTraceEnabled()) {logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());}// 返回要代理的接口,除了bean自身的接口外,spring还加入的了自己的接口// 例如: SpringProxy,Advised,DecoratingProxy等。Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);}
Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);

拦截器是自身,直接找invoke方法:

 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object oldProxy = null;boolean setProxyContext = false;TargetSource targetSource = this.advised.targetSource;Object target = null;try {// 前面的这些判断就是特定的方法,不用代理,直接放行。if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {// The target does not implement the equals(Object) method itself.return equals(args[0]);}else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {// The target does not implement the hashCode() method itself.return hashCode();}else if (method.getDeclaringClass() == DecoratingProxy.class) {// There is only getDecoratedClass() declared -> dispatch to proxy config.return AopProxyUtils.ultimateTargetClass(this.advised);}else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&method.getDeclaringClass().isAssignableFrom(Advised.class)) {// Service invocations on ProxyConfig with the proxy config...return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);}// 到这里开始代理。Object retVal;if (this.advised.exposeProxy) {// Make invocation available if necessary.oldProxy = AopContext.setCurrentProxy(proxy);setProxyContext = true;}// Get as late as possible to minimize the time we "own" the target,// 得到代理对象target = targetSource.getTarget();Class<?> targetClass = (target != null ? target.getClass() : null);// 从advised中得到所有的拦截器类型集合,这个方法中已经将增强类型包装为拦截器类型了。List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);if (chain.isEmpty()) {// 如果这个方法没有拦截器,那么直接放行。Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);}else {// 如果有拦截器,那么组成一个拦截器链,逐一执行。MethodInvocation invocation =new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);retVal = invocation.proceed();}// Massage return value if necessary.Class<?> returnType = method.getReturnType();if (retVal != null && retVal == target &&returnType != Object.class && returnType.isInstance(proxy) &&!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {// Special case: it returned "this" and the return type of the method// is type-compatible. Note that we can't help if the target sets// a reference to itself in another returned object.retVal = proxy;}else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {throw new AopInvocationException("Null return value from advice does not match primitive return type for: " + method);}return retVal;}finally {if (target != null && !targetSource.isStatic()) {// Must have come from TargetSource.targetSource.releaseTarget(target);}if (setProxyContext) {// Restore old proxy.AopContext.setCurrentProxy(oldProxy);}}}

特殊的方法直接放行;

从切面中找出匹配这个方法的切面,在从中将增强封装为拦截器类型MethodInterceptor。注意:spring找出的切脉是所有使用这个类的,执行个方法的时候还要在从这个切面中找出匹配自己方法的切脉。

拦截执行链

 public Object proceed() throws Throwable {// We start with an index of -1 and increment early.if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {return invokeJoinpoint();}Object interceptorOrInterceptionAdvice =this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {// 这里是处理动态的方法拦截的。不考虑。。。。。。}else {// It's an interceptor, so we just invoke it: The pointcut will have// been evaluated statically before this object was constructed.return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);}}

没执行一次,就从链中拿出一个拦截器,在执行。执行invoke时,传的时this,也就是ReflectiveMethodInvocation类,这个类包含所有的参数:

MethodInvocation invocation =new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);

proxy:代理后的对象
target:被代理对象
method:执行的方法
args:方法参数
targetClass:被代理的类型
chain:拦截器的集合

开发者只需要关注自己的增强业务即可。在业务中执行invocation.proceed();调用下一个拦截器

有个问题了顺序呢?切脉你的顺序的?spring为我们提供的before,after时如何排序的呢?

排序问题再找切面的时候就已经拍好了,代理的时候不用管了,直接按照顺序代理就可以了。下一篇介绍解析切面类。会提及排序的问题。

【Spring-AOP】底层类AbstractAutoProxyCreator分析相关推荐

  1. Spring AOP底层实现原理(动态代理)

    什么是AOP? AOP(面向切面编程)通过预编译的方式 和 运行期动态代理的方式来实现程序功能统一维护的一种方式,是OOP(面向对象编程)的延续.利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业 ...

  2. Spring AOP底层实现原理

    1.spring的AOP底层是由 JDK提供的动态代理技术 和 CGLIB(动态字节码增强技术)实现. 2.JDK动态代理:Jdk动态代理只针对于接口操作. 3.CGLIB:可以针对没有接口的java ...

  3. Spring AOP底层原理

    什么是AOP AOP:Aspect Oriented Programing(面向切面编程) 采用横向抽取机制,取代传统继承体系重复性代码(性能监视.事务管理.安全检查.缓存)即代理机制 使用纯JAVA ...

  4. Spring AOP底层实现- JDK动态代理和CGLIB动态代理

    Spring AOP是运行时织入的,那么运行时织入到底是怎么实现的呢?答案就是代理对象. 代理又可以分为静态代理和动态代理. 静态代理:由程序员创建或特定工具自动生成源代码,再对其编译.在程序运行前, ...

  5. spring aop源码实现分析

    1. 先分析Advice before执行Cglib2AopProxy的intercept方法: /*** General purpose AOP callback. Used when the ta ...

  6. java bean参数清空_Java互联网架构-Spring IOC底层源码分析

    欢迎关注头条号:java小马哥 周一至周日早九点半!下午三点半!精品技术文章准时送上!!! 精品学习资料获取通道,参见文末 spring ioc是spring的核心之一,也是spring体系的基础,那 ...

  7. Spring AOP 底层原理_001----AspectJ与CGLIB介绍

    http://www.ibm.com/developerworks/cn/java/l-aspectJ/index.html中介绍了What is AspectJ . AspectJ是一个代码生成工具 ...

  8. spring aop JointPoint类

  9. Spring AOP概述及底层实现原理

    Spring AOP概述及底层实现原理 aop概述 AOP全称为Aspect Oriented Programming的缩写,意为:面向切面编程.将程序中公用代码进行抽离,通过动态代理实现程序功能的统 ...

  10. Spring AOP方法分析

    Spring AOP方法分析 此示例显示如何配置Spring AOP方法概要分析.我们可以在任何服务(或其他)类中使用Spring AOP和任何方法,而无需在任何服务类中编写任何一行分析代码.面向方面 ...

最新文章

  1. 爬虫之观察js的执行过程
  2. 乔布斯+斯坦福演讲+Stay Hungry. Stay Foolish.
  3. 直接下载mongodb版本
  4. 把企业分“三只鸟”的发展好比“三个策略”
  5. 周三多管理学第七版pdf_为什么说管理学原理是企业领导的必修课?
  6. SAP BW系统日常维护日常工作及常见的Infopackage错误
  7. spark 用户画像挖掘分析_如何基于Spark进行用户画像?
  8. Amazon.com 和 store.apple.com 哪个的购物体验更好?
  9. 巨杉数据库完成数亿元D轮融资,引领金融级分布式数据库发展
  10. 30岁,我从前端转型管理成功了
  11. 17、【易混淆概念集】第十一章1 项目风险 风险临界值 VS 风险承受力 风险管理流程 风险管理及变更流程 规划风险管理 识别风险
  12. 手把手教你使用Admob广告中介
  13. 用Matlab将坐标添加到地图上
  14. Python对Excel文件多表对多表之间的匹配(两种不同表头)——之json版
  15. mysql host 为%_mysql中host为%是什么意思
  16. 莽撞小子终到迟暮中年 弗朗西斯择队目标转换(转)
  17. QGraphicsView图形视图框架使用(六)图元动画
  18. redhat7 mysql lamp_RHEL7 yum安装配置LAMP服务器(Apache+PHP+MySql)
  19. 泰坦尼克号生存预测python_基于Python sklearn应用逻辑回归对泰坦尼克乘客存活做预测(一)...
  20. MPLS virtual private network 跨域方案实现原理

热门文章

  1. 毕业生推荐表特长计算机专业,优秀毕业生推荐表个人简历怎么写
  2. kettle在linux定时任务_linux环境下kettle部署(JDK安装配置,kettle安装配置,资源库配置,定时执行job)...
  3. java jquery分页_如何最简单的实现java分页
  4. catalina 无法验证macos_拿什么拯救你,我的macOS Catalina——完整版补救措施来啦...
  5. 自动驾驶 10-1: 3D 几何和参考系3D Geometry and Reference Frames
  6. 人工智能中的深度结构学习 Learning deep architectures for AI - Yoshua Bengio
  7. 【网络入侵检测】K均值与层次聚类分析(sklearn,scipy,手写实现)
  8. 正则只能输入数字java_正则表达式限制输入字符,数字,汉字等
  9. 102 二叉树层序遍历Binary Tree Level Order Traversal @ Python
  10. 深度学习(一):神经元模型、感知机与BP算法