主要说下spring里aop的生效的原理吧,并不是讲底层的cglib和gdk动态代理。
还是老一套的分析流程,先找到了aop的标签的handler,然后看下在解析这个标签的时候,都干了些什么,其实主要就是看下注册了哪些bean,哪些beanPostProcessor. 因为看了那么多的spring的功能实现,基本都是通过这些beanPostProcessor来搞事情的,这个应该也不例外。
Ok,首先一眼会看到,把我们配置的pointCut,advisoe等组装成beanDefinition,向容器注册,这些bean的主要作用只是记录我们配置的那些数据(切入点,目标类,intercepter类等等),并不是什么很重要的部分。然后还看到注册了一个类 :AspectJAwareAdvisorAutoProxyCreator, 这个类是spring中aop生效的核心。
看下继承关系,发现它实现了beanPostProcessor这个接口,ok,和我们一开始的猜测是一样的,然后再看下里边的实现,然后具体里边的实现呢,就不很详细的写了,大体的流程是这样的。
一个Bean开始实例化—> 调用AspectJAwareAdvisorAutoProxyCreator里实例化bean的回调接口,看下能否提前将bean实例化,并创建代理,然后返回最终的代理类 —> 上述失败后,走正常的实例化流程 —> 在bean实例初始化后,调用AspectJAwareAdvisorAutoProxyCreator的beanpostProcessor回调接口 —> 如果还没有拿到所有的advisor实例,先拿到容器里所有的advisor实例,然后for循环去判断当前的这个bean是否应该进行代理,不应该的话,直接返回 —> 根据advisor中的信息,开始对bean进行代理,注意,如果这个bean有多个advisor的话,这里会把适用的advisor都拿出来,作为代理中的interceptor,然后选择采用哪种代理方式,进行底层的代理过程,最后返回被代理后的类。
这里需要注意的是,AspectJAwareAdvisorAutoProxyCreator一定要先于其他普通的bean被实例化,然后,回顾下容器初始化的过程,确实是会先实例化所有的processor,最后才会对普通的bean进行实例。 具体什么样的bean会被实例,什么样的会被延迟实例化,前面的文章中有专门讲过,这里就不多说了。ps:这些beanPostProcessor 内部也是可以设置实例化的优先级的,高优先级的会被先初始化,这个有的时候还是比较重要的,需要留意下。