SpingAOP源码研究

阅读更多

     如果之前没有读过Spring源码,建议先看一下我之前写的一个实现AOP的小demo

 

 

     在看SpingAOP源码之前先简单说一下SpingIOC的实现机制。SpingIOC的中最核心的接口是BeanFactory它更像是IOC容器的一个最基本的功能说明书,它有一个底层的实现类DefaultListableBeanFactory这个类基本上实现了BeanFactory体系中的所有重要功能,只有就是我们所熟悉的ApplicationContext。它是在BeanFactory的基础上做了扩展。继承了MessageSource, ApplicationEventPublisher, ResourcePatternResolver等接口以增强除BeanFactory基本功能之外的功能。ApplicationContext的子类基本上使用的就是DefaultListableBeanFactory。

 

IOC容器的初始化步骤:

     1> 定位Resource资源

     2> 创建DefaultListableBeanFactory

     3> 创建处理资源的BeanDefinitionReader

     4> 将Resource解析为Document

     5> 将Document解析为Spring定义的内部数据结构BeanDefinition

     6> 将BeanDefinition注册到Factory的CurrentHashMap中

     7> 创建对象(BeanFactory,Constructor,CGLIB)

     8> 解决依赖关系注入Property(期间会创建所有直接依赖或者间接依赖的类,直到这些类都创建并初始化完成之后,主类才会初始化完成)

     9> 将Bean注册到DefaultSingletonBeanRegistry的ConcurrentHashMap中 SpingIOC是非常强大的强大的副作用就是代码不容易理解。所以说肯定是没有我之前写的那个AOP小Demo好理解了。首先来看AOP通知接口的体系结构。

 

     SpingIOC是非常强大的强大的副作用就是代码不容易理解。所以说肯定是没有我之前写的那个AOP小Demo好理解了。首先来看AOP通知接口的体系结构。
       SpingAOP源码研究_第1张图片
 

之后是切入点:

   
SpingAOP源码研究_第2张图片

还有一个Advisor(通知器),它用来将Advice和Pointcut组织在一起


  想要调用代理方法,必须要先有代理对象,那么代理对象是在哪产生的?代理对象其实是在一个处理器AbstractAutoProxyCreator中产生的。用过Spring中处理器的人肯定知道实现BeanPostProcessor接口,然后覆盖postProcessBeforeInitialization,postProcessAfterInitialization两个方法就可以在bean执行init方法前后来处理逻辑了。其实现原理其实很简单,在初始化Bean时可以看到如下代码


SpingAOP源码研究_第3张图片
 分别是前置处理,init方法调用,后置处理。看一下生成代理对象类AbstractAutoProxyCreator的类签名



 
SpingAOP源码研究_第4张图片
 

     这样明白了,其实AbstractAutoProxyCreator类就是处理器。如果一个Bean需要创建代理对象的话,就会在这个Bean的init方法执行完之后调用后置处理器创建。创建完之后就会被放置到AbstractAutoProxyCreator类中的一个ConcurrentHashMap中



 

由于我的目标对象实现了接口所以使用的是JDK代理,否则的话会使用CGLIB代理。


SpingAOP源码研究_第5张图片

这是最核心的类,所有被代理的方法都会调用它的invoke方法其中有一个字段

 

	/** Config used to configure this proxy */
	private final AdvisedSupport advised;

 下面是它的截图

 


SpingAOP源码研究_第6张图片

 

 

只要搞定它是怎么来的,就会知道通知,切入点,目标类是怎么产生的。

想向下追两个方法都很有用

 

SpingAOP源码研究_第7张图片
 

在这里判断了是使用CGLIB创建代理还是JDK创建代理

 

SpingAOP源码研究_第8张图片
 

可以看到之前那个万能的字段其实是ProxyCrentorSupport类的实例,还记得之前创建代理的AbstractAutoProxyCreator吗,它们有着共同的基类。ProxyConfig为它的子类提供了配置属性。

 


SpingAOP源码研究_第9张图片

 

下面就要追一下这两个类之间是怎么建立关系的。上图调用createAopProxy(this)函数最开始的调用者是AbstractAutoProxyCreator也就是说这个this其实是ProxyFactory的实例


SpingAOP源码研究_第10张图片



SpingAOP源码研究_第11张图片

 

 

可以看到ProxyFactory又是ProxyCreatorSupport的子类。

那么proxyFactory又是怎么来的?


SpingAOP源码研究_第12张图片
 

 

这样也就建立了ProxyCrentorSupport类与AbstractAutoProxyCreator的关系 。也就是说ProxyCrentorSupport在创建代理的工厂AbstractAutoProxyCreator与代理类之间建立了一个桥梁,真正有用的数据像通知,切入点,目标类等最初还是AbstractAutoProxyCreator提供的。ProxyCrentorSupport也起到屏蔽AbstractAutoProxyCreator中的一些敏感信息,防止被代理类获取到作用。ProxyCrentorSupport还是一个抽象工厂,是非常经典的抽象工厂模式的应用。

可以稍微追一下advisor是从哪来的


SpingAOP源码研究_第13张图片


 现在来看JdkDynamicAopProxy中invoke是怎么执行的。首先它会创建一个ReflectiveMethodInvocation实例,然后让这个实例来调用proceed方法。这个ReflectiveMethodInvocation就相当于之前小Demo的ApplicationFilterChain。其结构如下


SpingAOP源码研究_第14张图片


 其中每一个advice被调用时都会把自身实例传入其中,然后调完通知方法之后就会重新调用ReflectiveMethodInvocation实例的proceed方法。这样便形成了回调机制,也就实现了AOP的功能(跟我的小demo原理一样)。其他通知与前置通知类似,异常通知是直接让你执行一个try…catch块环绕的代码,这样报错之后就会被处理。至于最终通知是把proceed放在了一个try…finally中。

 

  • SpingAOP源码研究_第15张图片
  • 大小: 7 KB
  • SpingAOP源码研究_第16张图片
  • 大小: 24.3 KB
  • SpingAOP源码研究_第17张图片
  • 大小: 9.8 KB
  • SpingAOP源码研究_第18张图片
  • 大小: 4.6 KB
  • SpingAOP源码研究_第19张图片
  • 大小: 36.6 KB
  • SpingAOP源码研究_第20张图片
  • 大小: 12.2 KB
  • SpingAOP源码研究_第21张图片
  • 大小: 41.8 KB
  • SpingAOP源码研究_第22张图片
  • 大小: 20.8 KB
  • SpingAOP源码研究_第23张图片
  • 大小: 20.4 KB
  • SpingAOP源码研究_第24张图片
  • 大小: 48.6 KB
  • SpingAOP源码研究_第25张图片
  • 大小: 44.8 KB
  • SpingAOP源码研究_第26张图片
  • 大小: 23.9 KB
  • SpingAOP源码研究_第27张图片
  • 大小: 24 KB
  • SpingAOP源码研究_第28张图片
  • 大小: 13.2 KB
  • SpingAOP源码研究_第29张图片
  • 大小: 12.7 KB
  • SpingAOP源码研究_第30张图片
  • 大小: 74.1 KB
  • SpingAOP源码研究_第31张图片
  • 大小: 16.2 KB
  • SpingAOP源码研究_第32张图片
  • 大小: 25.4 KB
  • 查看图片附件

你可能感兴趣的:(spring,aop)