AOP与IOC的连接

接着之前IOC的Bean的拓展,咱们再联结AOP一起去思考。那么AOP其实须要将之前的Bean进行代理,所以须要抉择适合的切入点整合IOC的一整套流程。所以应该是在初始化之后的处理器BeanPostProcessor#postProcessAfterInitialization应用代理进行接入替换。而首先咱们会有EnableAspectJAutoProxy注解进行将该后置处理器进行注册,当然咱们这里进行代理之后应用的援用也会扭转,所以这里会针对早起的援用会有一个map进行存储应用SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference进行拓展,供前面应用aop接入。其中咱们的后置处理器是在EnableAspectJAutoProxy注解,通过AspectJAutoProxyRegistrar引入AnnotationAwareAspectJAutoProxyCreator进行拓展。

AOP的概念

首先咱们先对aop的概念有一个理解,而后咱们将这些概念进行建模设置对应的接口,同时将这些接口进行组合,最终去实现咱们须要的面向切面的性能。

  1. Join Point(连接点):程序中须要进行切面的程序执行过程的点。比方办法调用,异样解决,Spring AOP反对办法级别的连接点。
  2. Pointcut(切入点):辨认程序连接点的模式演绎。
  3. Adice(告诉):须要切入之后执行的办法,分Before Adice、After Adice、After Returning Adice、After Throwing Adice、Around Adice
  4. Aspect(切面):切入点和告诉的联合
  5. Target Object:指标对象
  6. AOP proxy:代理对象
  7. Weaving(织入):将告诉通过切入点织入连接点

AOP的实现总概

AOP所要解决的事件就是想要查找一些特定的办法或者程序执行中的一些点,在这些点四周进行执行别的办法,其实也就是织入这个概念。而实现的基本原理上是依据动静代理进行实现。而咱们应用JDK的动静代理进行解说。

AOP的接口

  1. Join Point:org.aopalliance.intercept.Joinpoint接口,次要是process执行办法
  2. Pointcut:org.springframework.aop.Pointcut接口,次要是class过滤和办法过滤办法,也就是查找合乎切面的连接点的形象
  3. Advice:

    1. org.aopalliance.aop.Advice接口
    2. org.springframework.aop.BeforeAdvice接口
    3. org.springframework.aop.AfterAdvice接口
    4. org.springframework.aop.AfterReturningAdvice接口
    5. org.springframework.aop.ThrowsAdvice接口
  4. AOP Object:org.springframework.aop.framework.AopProxy接口
  5. Weaving:org.aopalliance.intercept.MethodInvocation接口,其实是Joinpoint接口的增强,同时也须要将告诉进行注入过来进行切面的时候进行调用

AOP整体串联

首先咱们须要把所有的切面找到,这样咱们才有判断条件找到连接点。而后咱们须要对每一个Bean依据收集起来的切面的切入点进行判断是否须要代理,所以依据找到接入点将切面的的告诉进一步接入代理,实现整个过程。咱们将这些过程拆解为以下步骤

  1. 切面的收集
  2. 所有切面的切入点的判断
  3. 找到适合的连接点的指标对象的同时将该切面的告诉收集供生成代理对象
  4. 将收集好的告诉和指标对象生成代理对象注入

切面的收集

切面的收集应该在Bean的实例化之前,所以放在实例化前后置处理器InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation。所以咱们查看AnnotationAwareAspectJAutoProxyCreator#postProcessBeforeInstantiation。Spring的AOP解决这里须要做一个判断,对切面这些Bean不须要解决,所以会判断这个Bean的状况。这在这个时候会去获取所有的告诉(Advice),同时也会把切入点(Pointcut)进行收集。那么收集所有告诉的时候就须要去获取所有的切面。而最初会在BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors。会获取所有的Bean,判断Bean是否有Aspect注解。有Aspect注解的Bean代表切面,同时去获取有告诉注解将这些办法转换为Advice

所有切面的切入点的判断

再Bean初始化之后的拓展点进行判断BeanPostProcessor#postProcessAfterInitialization,往后执行获取拦截器getAdvicesAndAdvisorsForBean进行判断是否须要进行代理。获取所有候选的Advisor,其中一些是PointcutAdvisor,存在切入点,会依据外面的条件判断,将match的Advisor返回。

依据符合条件的告诉进行生成代理对象

应用ProxyFactory进行生成代理,将满足的告诉Advisor增加,而后依据工厂模式结构代理对象。咱们以JdkDynamicAopProxy举例。JDK的动静代理是用Proxy#newProxyInstance进行实现的,咱们这个时候曾经找好了合乎这个Bean上面的告诉,咱们只有依据不同的类型将告诉依照程序执行即可。Spring是应用责任链的形式去执行多个告诉的形式。回过头来咱们说的织入就是将告诉依据切入点切入连接点,而Joinpoint就是指标对象和切面的组合。其中Spring只反对办法级别的代理,所以是MethodInvocation的拓展Joinpoint接口,而MethodInvocation的实现是ReflectiveMethodInvocation。首先咱们须要将告诉(Advice)适配成MethodInterceptor这样能够应用责任链的形式执行所有告诉。最初ReflectiveMethodInvocation联合适配之后的MethodInterceptor造成代理对象须要执行的残缺链路。

注入代理对象

返回代理对象进行缓存