spring注解开发(四)aop

版权声明:转载请注明出处 https://blog.csdn.net/Lee_Suoer/article/details/82379870

aop的使用

建立目标方法类:

建立切面类

//标注这是一个切面类
@Aspect
public class LogAspects {
    //抽取公共的切入点表达式
    //1、本类引用
    //2、其他的切面引用
    @Pointcut("execution(public int com.spring.demo.aop.Calculator.*(..))")
    public void pointCut(){}

    //@Before在目标方法之前切入;切入点表达式(指定在哪个方法切入)
    @Before("pointCut()")
    public void logStart(JoinPoint joinPoint){
        Object[] args = joinPoint.getArgs();
        System.out.println(""+joinPoint.getSignature().getName()+"运行。。。@Before:参数列表是:{"+ Arrays.asList(args)+"}");
    }

    @After("pointCut()")
    public void logEnd(JoinPoint joinPoint){
        System.out.println(""+joinPoint.getSignature().getName()+"结束。。。@After");
    }

    //JoinPoint一定要出现在参数表的第一位
    @AfterReturning(value="pointCut()",returning="result")
    public void logReturn(JoinPoint joinPoint,Object result){
        System.out.println(""+joinPoint.getSignature().getName()+"正常返回。。。@AfterReturning:运行结果:{"+result+"}");
    }

    @AfterThrowing(value="pointCut()",throwing="exception")
    public void logException(JoinPoint joinPoint,Exception exception){
        System.out.println(""+joinPoint.getSignature().getName()+"异常。。。异常信息:{"+exception+"}");
    }
}

在配置类中将切面和目标类都配置到spring中

正常执行情况

有异常的情况下

打印了异常信息

aop原理分析

@EnableAspectJAutoProxy;注入了一个组件  AspectJAutoProxyRegistrar

AspectJAutoProxyRegistrar这个组件注册了AnnotationAwareAspectJAutoProxyCreator

AnnotationAwareAspectJAutoProxyCreator:这个组件最终是实现了

SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware

最主要的就是对bean的初始化前后做了一些事情,和传递了beanFactory

程序的执行流程

刚开始传给的注解标注的类,,也就是配置类,,进行注册,然后调用  refresh();这个方法做了很多操作

public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {
      // Prepare this context for refreshing.
      prepareRefresh();

      // Tell the subclass to refresh the internal bean factory.
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // Prepare the bean factory for use in this context.
      prepareBeanFactory(beanFactory);

      try {
         // Allows post-processing of the bean factory in context subclasses.
         postProcessBeanFactory(beanFactory);

         // Invoke factory processors registered as beans in the context.
         invokeBeanFactoryPostProcessors(beanFactory);

         // Register bean processors that intercept bean creation.
         拦截bean的创建,注册BeanPostProcessors
         registerBeanPostProcessors(beanFactory);

         // Initialize message source for this context.
         initMessageSource();

         // Initialize event multicaster for this context.
         initApplicationEventMulticaster();

         // Initialize other special beans in specific context subclasses.
         onRefresh();

         // Check for listener beans and register them.
         registerListeners();

         // Instantiate all remaining (non-lazy-init) singletons.
         finishBeanFactoryInitialization(beanFactory);

         // Last step: publish corresponding event.
         finishRefresh();
      }

      catch (BeansException ex) {
         if (logger.isWarnEnabled()) {
            logger.warn("Exception encountered during context initialization - " +
                  "cancelling refresh attempt: " + ex);
         }

         // Destroy already created singletons to avoid dangling resources.
         destroyBeans();

         // Reset 'active' flag.
         cancelRefresh(ex);

         // Propagate exception to caller.
         throw ex;
      }

      finally {
         // Reset common introspection caches in Spring's core, since we
         // might not ever need metadata for singleton beans anymore...
         resetCommonCaches();
      }
   }
}

跟踪一下注册BeanPostProcessors

public static void registerBeanPostProcessors(
      ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

   String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

   // Register BeanPostProcessorChecker that logs an info message when
   // a bean is created during BeanPostProcessor instantiation, i.e. when
   // a bean is not eligible for getting processed by all BeanPostProcessors.
   int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
   beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

   // Separate between BeanPostProcessors that implement PriorityOrdered,
   // Ordered, and the rest.
   对postProcessorNames进行归类
   List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
   List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
   List<String> orderedPostProcessorNames = new ArrayList<>();
   List<String> nonOrderedPostProcessorNames = new ArrayList<>();
   for (String ppName : postProcessorNames) {
      if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
         BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
         priorityOrderedPostProcessors.add(pp);
         if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
         }
      }
      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
         orderedPostProcessorNames.add(ppName);
      }
      else {
         nonOrderedPostProcessorNames.add(ppName);
      }
   }

   // First, register the BeanPostProcessors that implement PriorityOrdered.
  先注册PriorityOrdered类型的BeanPostProcessors
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

   // Next, register the BeanPostProcessors that implement Ordered.
再注册Ordered类型的BeanPostProcessors
   List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
   for (String ppName : orderedPostProcessorNames) {
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      orderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
         internalPostProcessors.add(pp);
      }
   }
   sortPostProcessors(orderedPostProcessors, beanFactory);
   registerBeanPostProcessors(beanFactory, orderedPostProcessors);

   // Now, register all regular BeanPostProcessors.
   List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
   for (String ppName : nonOrderedPostProcessorNames) {
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      nonOrderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
         internalPostProcessors.add(pp);
      }
   }
   registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

   // Finally, re-register all internal BeanPostProcessors.
最后注册其他的BeanPostProcessors
   sortPostProcessors(internalPostProcessors, beanFactory);
   registerBeanPostProcessors(beanFactory, internalPostProcessors);

   // Re-register post-processor for detecting inner beans as ApplicationListeners,
   // moving it to the end of the processor chain (for picking up proxies etc).
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

最后把BeanPostProcessor注册到BeanFactory中;

在看一下最后初始化所有非懒加载的单实例bean,也就是我们定义的bean(目标类和切面)

遍历获取容器中所有的Bean,依次创建对象

创建Bean的实例
populateBean;给bean的各种属性赋值
 initializeBean:初始化bean;
                        1)、invokeAwareMethods():处理Aware接口的方法回调
                        2)、applyBeanPostProcessorsBeforeInitialization():应用后置处理器的postProcessBeforeInitialization()
                        3)、invokeInitMethods();执行自定义的初始化方法
                        4)、applyBeanPostProcessorsAfterInitialization();执行后置处理器的postProcessAfterInitialization();
 BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)创建成功;--》aspectJAdvisorsBuilder

 * AnnotationAwareAspectJAutoProxyCreator【InstantiationAwareBeanPostProcessor】    的作用:
 * 1)、每一个bean创建之前,调用postProcessBeforeInstantiation();
 *         关心目标类和切面类的创建
 *         1)、判断当前bean是否在advisedBeans中(保存了所有需要增强bean)
 *         2)、判断当前bean是否是基础类型的Advice、Pointcut、Advisor、AopInfrastructureBean,
 *             或者是否是切面(@Aspect)
 *         3)、是否需要跳过
 *             1)、获取候选的增强器(切面里面的通知方法)【List<Advisor> candidateAdvisors】
 *                 每一个封装的通知方法的增强器是 InstantiationModelAwarePointcutAdvisor;
 *                 判断每一个增强器是否是 AspectJPointcutAdvisor 类型的;返回true
 *             2)、永远返回false
 * 
 * 2)、创建对象
 * postProcessAfterInitialization;
 *         return wrapIfNecessary(bean, beanName, cacheKey);//包装如果需要的情况下
 *         1)、获取当前bean的所有增强器(通知方法)  Object[]  specificInterceptors
 *             1、找到候选的所有的增强器(找哪些通知方法是需要切入当前bean方法的)
 *             2、获取到能在bean使用的增强器。
 *             3、给增强器排序
 *         2)、保存当前bean在advisedBeans中;
 *         3)、如果当前bean需要增强,创建当前bean的代理对象;
 *             1)、获取所有增强器(通知方法)
 *             2)、保存到proxyFactory
 *             3)、创建代理对象:Spring自动决定
 *                 JdkDynamicAopProxy(config);jdk动态代理;
 *                 ObjenesisCglibAopProxy(config);cglib的动态代理;
 *         4)、给容器中返回当前组件使用cglib增强了的代理对象;
 *         5)、以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程;
 *         
 *     
 *     3)、目标方法执行    ;
 *         容器中保存了组件的代理对象(cglib增强后的对象),这个对象里面保存了详细信息(比如增强器,目标对象,xxx);
 *         1)、CglibAopProxy.intercept();拦截目标方法的执行
 *         2)、根据ProxyFactory对象获取将要执行的目标方法拦截器链;
 *             List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
 *             1)、List<Object> interceptorList保存所有拦截器 5
 *                 一个默认的ExposeInvocationInterceptor 和 4个增强器;
 *             2)、遍历所有的增强器,将其转为Interceptor;
 *                 registry.getInterceptors(advisor);
 *             3)、将增强器转为List<MethodInterceptor>;
 *                 如果是MethodInterceptor,直接加入到集合中
 *                 如果不是,使用AdvisorAdapter将增强器转为MethodInterceptor;
 *                 转换完成返回MethodInterceptor数组;
 * 
 *         3)、如果没有拦截器链,直接执行目标方法;
 *             拦截器链(每一个通知方法又被包装为方法拦截器,利用MethodInterceptor机制)
 *         4)、如果有拦截器链,把需要执行的目标对象,目标方法,
 *             拦截器链等信息传入创建一个 CglibMethodInvocation 对象,
 *             并调用 Object retVal =  mi.proceed();
 *         5)、拦截器链的触发过程;
 *             1)、如果没有拦截器执行执行目标方法,或者拦截器的索引和拦截器数组-1大小一样(指定到了最后一个拦截器)执行目标方法;
 *             2)、链式获取每一个拦截器,拦截器执行invoke方法,每一个拦截器等待下一个拦截器执行完成返回以后再来执行;
 *                 拦截器链的机制,保证通知方法与目标方法的执行顺序;
 *         
 *     总结:
 *         1)、  @EnableAspectJAutoProxy 开启AOP功能
 *         2)、 @EnableAspectJAutoProxy 会给容器中注册一个组件 AnnotationAwareAspectJAutoProxyCreator
 *         3)、AnnotationAwareAspectJAutoProxyCreator是一个后置处理器;
 *         4)、容器的创建流程:
 *             1)、registerBeanPostProcessors()注册后置处理器;创建AnnotationAwareAspectJAutoProxyCreator对象
 *             2)、finishBeanFactoryInitialization()初始化剩下的单实例bean
 *                 1)、创建业务逻辑组件和切面组件
 *                 2)、AnnotationAwareAspectJAutoProxyCreator拦截组件的创建过程
 *                 3)、组件创建完之后,判断组件是否需要增强
 *                     是:切面的通知方法,包装成增强器(Advisor);给业务逻辑组件创建一个代理对象(cglib);
 *         5)、执行目标方法:
 *             1)、代理对象执行目标方法
 *             2)、CglibAopProxy.intercept();
 *                 1)、得到目标方法的拦截器链(增强器包装成拦截器MethodInterceptor)
 *                 2)、利用拦截器的链式机制,依次进入每一个拦截器进行执行;
 *                 3)、效果:
 *                     正常执行:前置通知-》目标方法-》后置通知-》返回通知
 *                     出现异常:前置通知-》目标方法-》后置通知-》异常通知

猜你喜欢

转载自blog.csdn.net/Lee_Suoer/article/details/82379870