经过供应链大佬的预面试,觉得自己在Spring这一块掌握地还是有些浅,痛定思痛,再次阅读源码。
在上一篇文章中我们已经分析了Spring IOC的一个大概过程,那么AOP又是在什么时候发生的呢?(这篇文章不讲动态代理,不讲切面切点通知,只讲代码流程。)
缘起
Spring AOP很关键的一步就是创建AOP 代理,那么这一动作是何时发生的呢?
众所周知(不知道也没关系),创建代理对象有一种专门的类叫ProxyCreator
, 那么如果是基于注解创建的话,这个类叫做AnnotationAwareAspectJAutoProxyCreator
, 如果去看它的继承关系你会发现,它实现了BeanPostProcessor
接口,这个接口我们在上篇文章中也提到了:Bean
的实例化主要经过三个方法:createBeanInstance
,populateBean
,initializeBean
.其中最后一个方法就是用来处理各种回调,其中就包括BeanPostProcessor
,那我们就接着上一节讲的BeanPostProcessor
的回调来继续讲。
开始
先到BeanPostProcessor
的后置处理这里,
AbstractAutowireCapableBeanFactory
1633行
1 | if (mbd == null || !mbd.isSynthetic()) { |
applyBeanPostProcessorsAfterInitialization
:
1 | public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) |
进入到AbstactAutoProxyCreator
,已经发现了ProxyCreator
的影子了有木有?:
1 | public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { |
wrapIfNecessary()
:
我就只截取关键代码啦
这里的意思就是说,如果我们这个Bean有Advice或者Advisor的话,那么我们就开始创建代理,很容易理解有木有?
createProxy()
:
这里代码略多,我就不贴了,它的核心逻辑就是先获取并设置一个代理工厂,然后从代理工厂里获取代理,方法的最后一句是这样的:
1 | return proxyFactory.getProxy(getProxyClassLoader()); |
来到Class ProxyFactory
:
1 | public Object getProxy(ClassLoader classLoader) { |
从名字就可以看出来,创建AopProxy
createAopProxy()
:
1 | protected final synchronized AopProxy createAopProxy() { |
createAopProxy()
:
从这里就可以看出,根据targetClass
有没有接口之类的,决定用Jdk动态代理还是Cglib
.
至此,createProxy()
已经完成,我们再回到上面ProxyFactory
的getProxy()
方法:
1 | public Object getProxy(ClassLoader classLoader) { |
继续看下jdk
代理的getProxy()
做了什么:
来到了熟悉的jdk
动态代理有木有。众所周知第三个参数是InvocationHandler
接口的实现类,这里用了this
, 说明这个类自己实现了InvocationHandler
接口,我们来看下它复写的invoke()
方法。这个方法就厉害了,它涉及到拦截器调用链的执行,我这里只截取了部分核心代码。
首先它会去获得当前方法的一个拦截器链,获得之后,如果这个chain不为空,我们就把这个拦截器链创建成一个method invocation,然后去执行。那么这个proceed()
就是一个责任链模式的执行过程。
总结
关于Spring的AOP, 我们要知道这么几个问题,
- 首先AOP从什么时候开始的,答案是
BeanPostProcessor
,也就是说,Spring AOP 会在 IOC 容器创建 bean 实例的最后对 bean 进行处理。其实就是在这一步进行代理增强。 - AOP分为两步,
createProxy
和getProxy
. 其中createProxy
有jdk
和cglib
两种方法。而getProxy
是我们最需要注意的。以jdk
动态代理为例,它的invoke方法里包含了以责任链模式对拦截器的调用。