不知道读者是否还记得,前面的章节中,我们学习了Spring是如何去获得增强方法或增强器,那么这一节中,我们主要来看看Spring是怎样去创建代理。首先我们来看一下创建代理的时序图。

1. AbstractAutoProxyCreator

在获取了对应的bean之后,便可以进行代理的创建了。

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);//决定对于给定的bean是否应该使用targetClass而不是他的接口代理//检查 proxyTargeClass设置及preserveTargetClass属性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);//用来控制代理工厂被配置之后,是否允许修改通知//缺省值为false(即在代理被配置之后,不允许修改代理的配置)proxyFactory.setFrozen(this.freezeProxy);if (advisorsPreFiltered()) {proxyFactory.setPreFiltered(true);}return proxyFactory.<strong>getProxy(getProxyClassLoader())</strong>;}

2. ProxyFactory

Sprin在创建代理的时候,又将功能委托给了ProxyFactory的类,所在在ProxyFactory的类中可以看到方法getProxy().

 public Object getProxy(ClassLoader classLoader) {return <strong>createAopProxy()</strong>.getProxy(classLoader);}

如果笔者进一步跟踪createAopProxy().getProxy(classLoader)的getProxy()的方法,我们将看到,这里将分为JDK代理的CGLIB的代理 。如下图所示。

3. ProxyCreatorSupport

接下来,我们跟踪代码进入createAopProxy().getProxy(classLoader)的createAopProxy()的方法里,该方法在ProxyCreatorSupport中被定义。

protected final synchronized AopProxy createAopProxy() {if (!this.active) {activate();}//创建代理return getAopProxyFactory().<strong>createAopProxy(this</strong>);}

4. DefaultAopProxyFactory

在上面的方法中,我们可以看,Srping又把方法委托给了DefaultAopProxyFactory的类去处理了。我们继续进入getAopProxyFactory().createAopProxy(this)的createAopProxy的方法内,可以看到真正创建代理的代码。

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {if (<strong>config.isOptimize()</strong> || <strong>config.isProxyTargetClass()</strong> || <strong>hasNoUserSuppliedProxyInterfaces(config)</strong>) {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);}}

5. 总结

对于创建代理,我们可以归结为以下几点:

1)        获取当前类中的属性

2)        添加代理接口

3)        封装Advisor并加入到ProxyFactory中

4)        设置要代理的类

5)        当然在Spring中还为子类提供了定制的函数customizeProxyFactory,子类可以在此函数中进行对ProxyFactory的进一步封装。

6)        进行获取代理操作

Spring源码之创建代理相关推荐

  1. Spring AOP 源码分析 - 创建代理对象

    1.简介 在上一篇文章中,我分析了 Spring 是如何为目标 bean 筛选合适的通知器的.现在通知器选好了,接下来就要通过代理的方式将通知器(Advisor)所持有的通知(Advice)织入到 b ...

  2. Spring源码-AOP(六)-自动代理与DefaultAdvisorAutoProxyCreator

    2019独角兽企业重金招聘Python工程师标准>>> Spring AOP 源码解析系列,建议大家按顺序阅读,欢迎讨论 Spring源码-AOP(一)-代理模式 Spring源码- ...

  3. Spring IOC 容器源码分析 - 创建原始 bean 对象

    1. 简介 本篇文章是上一篇文章(创建单例 bean 的过程)的延续.在上一篇文章中,我们从战略层面上领略了doCreateBean方法的全过程.本篇文章,我们就从战术的层面上,详细分析doCreat ...

  4. Spring IOC 容器源码分析 - 创建单例 bean 的过程

    1. 简介 在上一篇文章中,我比较详细的分析了获取 bean 的方法,也就是getBean(String)的实现逻辑.对于已实例化好的单例 bean,getBean(String) 方法并不会再一次去 ...

  5. Spring源码分析之AOP源码分析

    文章目录 前言 一.AOP回顾 二.源码分析 EnableAspectJAutoProxy注解 AnnotationAwareAspectJAutoProxyCreator 前言 Spring框架的两 ...

  6. Spring 源码分析(三) —— AOP(五)创建代理

    2019独角兽企业重金招聘Python工程师标准>>> 创建代理 代理的定义其实非常简单,就是改变原来目标对象方法调用的运行轨迹.这种改变,首先会对这些方法进行拦截,从而为这些方法提 ...

  7. Spring源码深度解析(郝佳)-学习-源码解析-创建AOP静态代理实现(八)

    继上一篇博客,我们继续来分析下面示例的 Spring 静态代理源码实现. 静态 AOP使用示例 加载时织入(Load -Time WEaving,LTW) 指的是在虚拟机载入字节码时动态织入 Aspe ...

  8. Spring源码深度解析(郝佳)-学习-源码解析-创建AOP静态代理(七)

    加载时织入(Load-Time Weaving ,LTW) 指的是在虚拟机加载入字节码文件时动态织入Aspect切面,Spring框架的值添加为 AspectJ LTW在动态织入过程中提供了更细粒度的 ...

  9. spring源码深度解析---创建AOP代理之获取增强器

    spring源码深度解析-创建AOP代理之获取增强器 在上一篇的博文中我们讲解了通过自定义配置完成了对AnnotationAwareAspectJAutoProxyCreator类型的自动注册,那么这 ...

  10. Spring源码学习笔记:经典设计模式之代理模式

    1.博客内容均出自于咕泡学院架构师第三期 2.架构师系列内容:架构师学习笔记(持续更新) 0.代理模式(Proxy Pattern) 指为其他对象提供一种代理,以控制对这个对象的访问.代理对象在客户端 ...

最新文章

  1. laravel mysql注入_laravel中如何利用反射实现依赖注入
  2. 批处理命令学习笔记——Start命令
  3. python条件语句-python条件、循环语句
  4. 笔记-计算机网络基础-计算机网络分类-总线型-星型-环状-树形-网状-网络拓扑结构...
  5. 正态分布的峰度和偏度分别为_ML中的正态分布
  6. Windows Server 2012R2之重复数据删除实战
  7. MediaPlay播放Stream时出现error 38等错误的原因
  8. iOS 使用 Core Plot 绘制统计图表入门
  9. 用juniversalchardet解决爬虫乱码问题
  10. MapReduce on Hbase
  11. php 修复excel 乱码,php下载excel乱码的解决方法
  12. XTU 1236 Fibonacci
  13. 【数理统计】卡方检验
  14. java经纬度格式_java经纬度格式转换
  15. 皮尔森残差_残差与标准化残差
  16. R语言ggplot2可视化在轴标签、轴标题中添加大于号、等于号等实战
  17. 对于如何长胖和减肥的研究
  18. Heartbeat超时值
  19. 解决ubuntu18.04无法连接wifi问题
  20. Linux系统挂起之后退出的方法

热门文章

  1. jvisualvm工具
  2. char与byte差异
  3. 有监督学习 无监督学习
  4. Angucomplete —— AngularJS 自动完成输入框
  5. web安全day20:今天讲清楚漏洞和木马的区别,最后一个实验演示通过445端口控制服务器
  6. CTF中文件与16进制互转及相关操作(Python3)
  7. Arts 第十二周(6/3 ~ 6/9)
  8. 比特币 的 正统 ——BCH
  9. 多个需要验证的输入框思路问题
  10. VS Code 调试 Angular 和 TypeScript 的配置