如果之前没有读过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通知接口的体系结构。
之后是切入点:
还有一个Advisor(通知器),它用来将Advice和Pointcut组织在一起
想要调用代理方法,必须要先有代理对象,那么代理对象是在哪产生的?代理对象其实是在一个处理器AbstractAutoProxyCreator中产生的。用过Spring中处理器的人肯定知道实现BeanPostProcessor接口,然后覆盖postProcessBeforeInitialization,postProcessAfterInitialization两个方法就可以在bean执行init方法前后来处理逻辑了。其实现原理其实很简单,在初始化Bean时可以看到如下代码
分别是前置处理,init方法调用,后置处理。看一下生成代理对象类AbstractAutoProxyCreator的类签名
这样明白了,其实AbstractAutoProxyCreator类就是处理器。如果一个Bean需要创建代理对象的话,就会在这个Bean的init方法执行完之后调用后置处理器创建。创建完之后就会被放置到AbstractAutoProxyCreator类中的一个ConcurrentHashMap中
由于我的目标对象实现了接口所以使用的是JDK代理,否则的话会使用CGLIB代理。
这是最核心的类,所有被代理的方法都会调用它的invoke方法其中有一个字段
/** Config used to configure this proxy */ private final AdvisedSupport advised;
下面是它的截图
只要搞定它是怎么来的,就会知道通知,切入点,目标类是怎么产生的。
想向下追两个方法都很有用
在这里判断了是使用CGLIB创建代理还是JDK创建代理
可以看到之前那个万能的字段其实是ProxyCrentorSupport类的实例,还记得之前创建代理的AbstractAutoProxyCreator吗,它们有着共同的基类。ProxyConfig为它的子类提供了配置属性。
下面就要追一下这两个类之间是怎么建立关系的。上图调用createAopProxy(this)函数最开始的调用者是AbstractAutoProxyCreator也就是说这个this其实是ProxyFactory的实例
可以看到ProxyFactory又是ProxyCreatorSupport的子类。
那么proxyFactory又是怎么来的?
这样也就建立了ProxyCrentorSupport类与AbstractAutoProxyCreator的关系 。也就是说ProxyCrentorSupport在创建代理的工厂AbstractAutoProxyCreator与代理类之间建立了一个桥梁,真正有用的数据像通知,切入点,目标类等最初还是AbstractAutoProxyCreator提供的。ProxyCrentorSupport也起到屏蔽AbstractAutoProxyCreator中的一些敏感信息,防止被代理类获取到作用。ProxyCrentorSupport还是一个抽象工厂,是非常经典的抽象工厂模式的应用。
可以稍微追一下advisor是从哪来的
现在来看JdkDynamicAopProxy中invoke是怎么执行的。首先它会创建一个ReflectiveMethodInvocation实例,然后让这个实例来调用proceed方法。这个ReflectiveMethodInvocation就相当于之前小Demo的ApplicationFilterChain。其结构如下
其中每一个advice被调用时都会把自身实例传入其中,然后调完通知方法之后就会重新调用ReflectiveMethodInvocation实例的proceed方法。这样便形成了回调机制,也就实现了AOP的功能(跟我的小demo原理一样)。其他通知与前置通知类似,异常通知是直接让你执行一个try…catch块环绕的代码,这样报错之后就会被处理。至于最终通知是把proceed放在了一个try…finally中。