• 搞懂aop四 原理


    package spring.learn.annotation.aopconfig;
    
    import org.springframework.aop.TargetSource;
    import org.springframework.aop.aspectj.AbstractAspectJAdvice;
    import org.springframework.aop.aspectj.AspectJAfterAdvice;
    import org.springframework.aop.aspectj.AspectJAfterThrowingAdvice;
    import org.springframework.aop.aspectj.AspectJAroundAdvice;
    import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator;
    import org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator;
    import org.springframework.aop.framework.ProxyProcessorSupport;
    import org.springframework.aop.framework.ReflectiveMethodInvocation;
    import org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor;
    import org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor;
    import org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator;
    import org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator;
    import org.springframework.aop.interceptor.ExposeInvocationInterceptor;
    import org.springframework.aop.support.AopUtils;
    import org.springframework.beans.factory.BeanFactoryAware;
    import org.springframework.beans.factory.ObjectFactory;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
    import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
    import org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory;
    import org.springframework.beans.factory.support.AbstractBeanFactory;
    import org.springframework.beans.factory.support.DefaultSingletonBeanRegistry;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.EnableAspectJAutoProxy;
    
    /**
     * @Description:
     * 注解AOP使用说明:
     * 1)导包
     *      <dependency>
     *          <groupId>org.springframework</groupId>
     *          <artifactId>spring-aspects</artifactId>
     *          <version>5.1.5.RELEASE</version>
     *       </dependency>
     * 2)定义切面类,切面方法
     *      @Pointcut 切点
     *      @Before("pointcut()")
     *      @After("pointcut()")
     *      @Around("spring.learn.annotation.aopconfig.LogAop.pointcut()") 切点的全名使用,配合ProceedingJoinPoint .proceed(); 使用
     *      @AfterReturning(value = "pointcut()",returning = "res")
     *      @AfterThrowing(value = "pointcut()",throwing = "e")
     * 3)启用AOP功能 @EnableAspectJAutoProxy
     *
     * AOP 原理
     *  1)注入 AnnotationAwareAspectJAutoProxyCreator 一个bean,bean的nameorg.springframework.aop.config.internalAutoProxyCreator 负责处理标有@Aspect注解的bean,继承结构如下
     *  {@link AnnotationAwareAspectJAutoProxyCreator }
     *      — {@link AspectJAwareAdvisorAutoProxyCreator}
     *          — {@link AbstractAdvisorAutoProxyCreator} 主要负责 多个增强满足条件的时候,如何有序执行
     *              — {@link AbstractAutoProxyCreator } 主要负责创建具体的代理对象
     *                  — {@link ProxyProcessorSupport }
     *                  - {@link SmartInstantiationAwareBeanPostProcessor }
     *                     - {@link InstantiationAwareBeanPostProcessor }
     *                        - {@link BeanPostProcessor}
     *                  - {@link BeanFactoryAware }
     * 2)创建AnnotationAwareAspectJAutoProxyCreator时机及流程.这个要从特殊的接口说起【InstantiationAwareBeanPostProcessor,BeanPostProcessor】
     *      1、关键点记录
     *      @see AbstractAdvisorAutoProxyCreator#setBeanFactory
     *      @see AbstractAutoProxyCreator#postProcessAfterInitialization 初始化后置处理器
     *      @see AbstractAutoProxyCreator#postProcessBeforeInstantiation 实例化前处理
     *
     *      2、流程
     *          2.1 registerBeanPostProcessors 注册后置处理器,来拦截所有bean的创建(AnnotationAwareAspectJAutoProxyCreator属于后置处理器)
     *          2.2 注册BeanPostProcessor会根据实现PriorityOrdered、Ordered的接口排序,没有实现的不排序,排序规则按照从小到大,越小的执行
     *          越优先。注册完成后将后置处理器交给bean工厂
     *          2.3 创建bean(该流程适用所有的bean的创建)
     *          @see AbstractBeanFactory#doGetBean 先检查单例缓存是否有手动注册的单例,如果获取不到去继续
     *          @see DefaultSingletonBeanRegistry#getSingleton(String, ObjectFactory) 再次尝试获取bean,如果获取不到就创建bean
     *          @see AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, Object[])
     *              2.3.1 在实例化之前执行后置处理器InstantiationAwareBeanPostProcessor,如果有对应后置处理器的实现postProcessBeforeInstantiation返回
     *              一个非空的对象,结束继续代理,然后遍历执行该接口的实现类的后置处理方法postProcessAfterInitialization,如果方法返回返回空结束遍历,
     *              将处理前的对象返回,否则直到遍历完所有。如果该方法返回的对象不为空,创建bean结束。
     *              @see AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition)
     *              2.3.2 前面流程走完如果没有创建的对象,则继续创建。
     *              @see AbstractAutowireCapableBeanFactory#doCreateBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
     *                  2.3.2.1 实例化bean
     *                  @see AbstractAutowireCapableBeanFactory#createBeanInstance(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
     *                  2.3.2.2 实例化后 允许后置处理器MergedBeanDefinitionPostProcessor修改bean的定义信息
     *                  2.3.2.3 初始化bean之属性赋值,先调用实例化的后置处理器postProcessAfterInstantiation,如果返回false则结束赋值;进行属性赋值;
     *                  属性赋值后,有机会执行 InstantiationAwareBeanPostProcessor#postProcessProperties,和postProcessPropertyValues
     *                  @see AbstractAutowireCapableBeanFactory#populateBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, org.springframework.beans.BeanWrapper)
     *                  2.3.2.3 初始化bean之初始化逻辑
     *                  @see AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
     *                      ·invokeAwareMethods执行知道的aware方法(BeanNameAware、BeanFactoryAware、BeanClassLoaderAware)
     *                      @see AbstractAutowireCapableBeanFactory#invokeAwareMethods
     *                      ·执行bean的初始化后置处理器的postProcessBeforeInitialization方法,具体可见lifecyle中的描述
     *                      @see AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
     *                      ·执行初始化方法,使用见lifecycle
     *                      @see AbstractAutowireCapableBeanFactory#invokeInitMethods
     *                      ·执行bean的初始化后置处理器的applyBeanPostProcessorsAfterInitialization方法
     *                      @see AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
     *                      ·todo 后面的逻辑暂时不做跟进
     * 3)创建代理对象,这个时候前面注册的bean,就会在满足条件的bean创建一个代理对象。
     *      1、在对象实例化之前执行实例化的后置处理器,这个时候做一些判断,其中shouldSkip是一个要点,这个方法会查找所有的候选增强并缓存,查找规则
     *       ①按照Advisor这个类型查找,这个是spring支持的增强;②构建AspectJ的增强,这个就是工作中常用的注解增强。
     *      然后遍历这些增强来判断if (advisor instanceof AspectJPointcutAdvisor && ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) ,这个判断是true,则返回true
     *      如果我们有自定义的 {@link TargetSource},在此处创建代理,就回产生一个代理对象,并将bean的名字放在targetSourcedBeans set集合中
     *      如果后面在为bean做增强代理的时候,会检查有没有被增强过,如果增强则不再继续增强了。
     *      @see AbstractAutoProxyCreator#postProcessBeforeInstantiation(java.lang.Class, java.lang.String)
     *          @see AspectJAwareAdvisorAutoProxyCreator#shouldSkip(java.lang.Class, java.lang.String)
     *      2、在对象初始化化之后调用实例化的后置处理器postProcessAfterInitialization,如果需要代理会调用wrapIfNecessary,这个方法再次用到了shouldSkip
     *      @see AbstractAutoProxyCreator#postProcessAfterInitialization(java.lang.Object, java.lang.String)
     *          @see AbstractAutoProxyCreator#wrapIfNecessary(java.lang.Object, java.lang.String, java.lang.Object)
     *          2.1、判断是否有必要包装增强
     *          2.2、 获取这个bean可用的增强方法,先获取候选的,再获取可用的,
     *          @see AbstractAdvisorAutoProxyCreator#findEligibleAdvisors(java.lang.Class, java.lang.String)
     *              2.2.1 findCandidateAdvisors,找到候选的增强,这个方法在shouldSikp中执行过
     *              2.2.2 findAdvisorsThatCanApply 找到候选中可以应用到当前bean的方法。
     *              调用AopUtils中的方法{@link AopUtils#findAdvisorsThatCanApply(java.util.List, java.lang.Class)}这个方法会处理当前bean再在候选增强中能有几个增强可用
     *              2.2.3 extendAdvisors 如果候选方法能应用到正在创建的bean,则再增加一个DefaultPointcutAdvisor,这个增强使用见aop流程分析里
     *              2.2.4 如果可用的增强不为空,则进行排序,按照切面的order排序从小到大排序,再按照切面的增强方法排序{@link AbstractAspectJAdvice}增强都是这个抽象类的实现,这个定义了增强执行
     *              @see org.springframework.aop.aspectj.autoproxy.AspectJPrecedenceComparator#compare(org.springframework.aop.Advisor, org.springframework.aop.Advisor)
     *          2.3、创建代理对象,如果前面能找到可用的增强的话。这里有一些东西需要说明一下,省的混乱。
     *          代理工厂创建了一个DefaultAopProxyFactory对象,这个对象可以根据目标类判断创建何种代理,代理负责创建代理对象
     *          @see AbstractAutoProxyCreator#createProxy(java.lang.Class, java.lang.String, java.lang.Object[], org.springframework.aop.TargetSource)
     *              2.3.1 创建代理工厂,这里使用无参构造器创建了一个默认aop代理工厂DefaultAopProxyFactory,这里预留了扩展{@link AbstractAutoProxyCreator#customizeProxyFactory(org.springframework.aop.framework.ProxyFactory)}
     *              2.3.2 创建代理这个时候默认的aop代理工厂会判断创建jdk还是cglib的对象
     *               @see org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy
     *              2.3.3 创建代理对象
     *              @see org.springframework.aop.framework.CglibAopProxy#getProxy(java.lang.ClassLoader)
     * 4) 代理对象的执行流程
     * @see org.springframework.aop.framework.CglibAopProxy.DynamicAdvisedInterceptor#intercept(java.lang.Object, java.lang.reflect.Method, java.lang.Object[], org.springframework.cglib.proxy.MethodProxy)
     *      1、新建一个方法调用,处理代理对象的方法调用new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
     *      @see ReflectiveMethodInvocation#proceed(),
     *      2、如果匹配的拦截方法的size为0,则执行目标方法,如果不相等,则取出匹配的第一个拦截方法
     *      // currentInterceptorIndex 值默认为-1
     *      if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
     *          return invokeJoinpoint();
     *      }
     *      @see ReflectiveMethodInvocation#proceed()
     *          2.1、取出第一个方法拦截器,执行invoke方法,将当前新建的方法调用设为线程共享变量,如果和面调用链有
     *          需要和这个方法调用对象,可以通过这个类的currentInvocation这个静态无参方法获取
     *          @see ExposeInvocationInterceptor#invoke
     *          2.2、去除第二个方法拦截器,继续执行invoke,这个方法拦截器如果放生异常,则会进入该方法的catch块,执行增强逻辑
     *          @see AspectJAfterThrowingAdvice#invoke
     *          2.3 第三个,如果这个方法执行结束并没有异常,则执行增强逻辑
     *          @see AfterReturningAdviceInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
     *          2.4 第四个,这个方法执行结束前,执行增强逻辑
     *          @see AspectJAfterAdvice#invoke
     *          2.5 第五个,开始执行环绕增强
     *          @see AspectJAroundAdvice#invoke(org.aopalliance.intercept.MethodInvocation)
     *          2.6 before
     *          @see MethodBeforeAdviceInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
     *          注:所有的增强是通过反射执行的
     *          @see AbstractAspectJAdvice#invokeAdviceMethod(org.aspectj.lang.JoinPoint, org.aspectj.weaver.tools.JoinPointMatch, java.lang.Object, java.lang.Throwable)
     *
     * @Author: liangjunhui
     * @Date: 2019/4/2 20:56
     */
    @EnableAspectJAutoProxy(proxyTargetClass = true)
    @Configuration
    public class TestAopConfig {
        @Bean
        public Mathcalcultar caccultar1(){
            return new Mathcalcultar();
        }
    
        @Bean
        public LogAop logAop(){
            return new LogAop();
        }
    }
    package spring.learn.annotation.aopconfig;
    
    public class Mathcalcultar {
        public int div(int n,int m){
            return n / m;
        }
    }
    Mathcalcultar
    package spring.learn.annotation.aopconfig;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.*;
    import org.springframework.core.Ordered;
    
    import java.util.Arrays;
    import java.util.List;
    
    @Aspect
    public class LogAop implements Ordered {
        @Pointcut("execution(public int spring.learn.annotation.aopconfig.Mathcalcultar.*(..))")
        public void pointcut(){
    
        }
        @Before("pointcut()")
        public void methodBefore(JoinPoint joinPoint){
            System.out.println(joinPoint.getSignature().getName()+"方法前执行,方法内的参数"+Arrays.asList(joinPoint.getArgs()));
        }
    
        @Override
        public int getOrder() {
            return 2147481648;
        }
    
         @AfterReturning(value = "pointcut()",returning = "res")
        public void methodAfterReturning(JoinPoint joinPoint,Object res){
            System.out.println(joinPoint.getSignature().getName()+"方法返回后执行,方法内的参数"+Arrays.asList(joinPoint.getArgs()));
            System.out.println("返回结果是:"+res);
        }
    
        @AfterThrowing(value = "pointcut()",throwing = "e")
        public void methodAfterThrowing(JoinPoint joinPoint , Exception e){
            System.out.println(joinPoint.getSignature().getName()+"方法异常后执行,方法内的参数"+Arrays.asList(joinPoint.getArgs()));
            System.out.println("异常信息:");
            e.printStackTrace();
        }
    
       @Around("spring.learn.annotation.aopconfig.LogAop.pointcut()")
       public Object methodAround(ProceedingJoinPoint joinPoint){
           List<Object> objects = Arrays.asList(joinPoint.getArgs());
           try {
               return joinPoint.proceed();
           } catch (Throwable throwable) {
               throwable.printStackTrace();
           }
           System.out.println(joinPoint.getSignature().getName()+"方法间执行,方法内的参数"+Arrays.asList(joinPoint.getArgs()));
           return null;
       }
    
        @After("pointcut()")
        public void methodAfter(JoinPoint joinPoint){
            System.out.println(joinPoint.getSignature().getName()+"方法后执行,方法内的参数"+ Arrays.asList(joinPoint.getArgs()));
        }
    }
    LogAop
  • 相关阅读:
    python 安装包总结
    python wmi使用
    Jquery
    查看linux操作系统位数
    三元
    git clone 指定分支的内容
    慕课网
    http://amazeui.org 后天框架
    tp between
    git pull
  • 原文地址:https://www.cnblogs.com/mao-yan/p/13554768.html
Copyright © 2020-2023  润新知