从源码的角度深入理解spring AOP原理及流程

从源码的角度深入理解spring AOP原理及流程

前言:

Spring作为java开发必用的开源框架之一,必然有它非常优秀的且不可替代的地方,其中springIOC和Aop就是设计的非常优秀的地方,今天一起来学习一下spring是如何实现AOP

AOP实现的思想:简单来讲就是使用了动态代理,对业务方法进行拦截增强(cglib或者jdk)

继续深入的思考一下如下问题:

  1. 如何创建动态代理
  2. 如何判断哪些类需要被代理增强,那些类不需要被增强
  3. 如何获取通知类
  4. ……

需要掌握的一些概念或技能:

  1. 动态代理
  2. 后置处理器
  3. Spring的注解的使用如@Import等
  4. 切面,通知、切点等aop相关的概念
  5. ……

下面开始跟大家一起学习SpringAOP

一、编写用于debug的aop的demo应用程序

1、业务类Calculator.java

@Component
public class Calculator {

    public int div(int x,int y){
        System.out.println("calculator div running...");
        return x/y;
    }
}

2、切面类LogAspects.java

@Aspect
@Component
public class LogAspects {

    @Pointcut("execution(public int cap1.Calculator.*(..))")
    public void pointCut(){}

    @Before(value = "pointCut()")
    public void logStart(JoinPoint joinPoint){
        System.out.println("start...");
        System.out.println(joinPoint.getSignature().getName());
        for(Object obj : joinPoint.getArgs()){
            System.out.println("----"+obj);
        }
        System.out.println(joinPoint.getTarget().toString());
    }

    @After(value = "pointCut()")
    public void logEnd(){
        System.out.println("end....");

    }

    @AfterReturning(value = "pointCut()",returning = "result")
    public void logReturn(Object result){
        System.out.println("return....");
        System.out.println("result = "+result);
    }

    @AfterThrowing(value = "pointCut()",throwing = "exception")
    public void logThrowing(Exception exception){
        System.out.println("throwing");
    }

    @Around(value = "pointCut()")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("around proceeding start....");
        Object proceed = joinPoint.proceed();
        System.out.println("around proceeding end");
        return proceed;
    }

}

3、配置类MainConfig.java

@Configuration
@ComponentScan
@EnableAspectJAutoProxy
public class MainConfig1 {

    @Bean
    public Person person(){
        return new Person();
    }
}

4、测试类Main1Test.java

public class Main1Test {

    @Test
    public void test(){
        AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(MainConfig1.class);

        for (String name : app.getBeanDefinitionNames()){
            System.out.println(name);
        }
        app.getBean(Calculator.class).div(4,2);
    }
}

上面简单的程序就可以模拟springaop啦,下面开始分析springaop工作的原理

在分析之前先说一下springaop的核心的一个类:

BeanName:org.springframework.aop.config.internalAutoProxyCreator

Class:AnnotationAwareAspectJAutoProxyCreator

二、源码分析

1、准备工作—准备向springIOC容器中注入AnnotationAwareAspectJAutoProxyCreator

(1)从EnableAspectJAutoProxy开关开始

从源码的角度深入理解spring AOP原理及流程

 

 (2)@Import注解的使用

从源码的角度深入理解spring AOP原理及流程

 (3)AspectJAutoProxyRegistrar#registerBeanDefinitions()

@Override
public void registerBeanDefinitions(
      AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

      AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
       ......
}

(4)AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary()

@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
   return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}

(5)AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary()

@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry,
      @Nullable Object source) {

   return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}

(6)AopConfigUtils#registerOrEscalateApcAsRequired()

@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry,
      @Nullable Object source) {

   Assert.notNull(registry, "BeanDefinitionRegistry must not be null");

   if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
      BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
      if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
         int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
         int requiredPriority = findPriorityForClass(cls);
         if (currentPriority < requiredPriority) {
            apcDefinition.setBeanClassName(cls.getName());
         }
      }
      return null;
   }

   RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
   beanDefinition.setSource(source);
   beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
   beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
   registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
   return beanDefinition;
}

上面的所有工作都是为了准备向IOC容器中注入AnnotationAwareAspectJAutoProxyCreator

2、向IOC容器中注入各种bean,包括后置处理器(beanpostProcessor)和业务bean,配置bean等所有的bean,这里注意下,向IOC容器中注入bean的时候是先注入后置处理器,然后再注入普通bean,其中后置处理器也是有注入的先后顺序。后置处理器的作用就是用于拦截bean的构建,可以在bean初始化的时候做一些拦截的动作。

下面开始分析代码

(1)AnnotationConfigApplicationContext#AnnotationConfigApplicationContext()

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
   this();
   register(annotatedClasses);
   refresh();
}

(2)AbstractApplicationContext#refresh()

@Override
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.
         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();
      }

(3)AbstractApplicationContext#registerBeanPostProcessors()先注入后置处理器

注入后置处理器和注入普通的bean的主要的流程差不多,就是时机比注入普通的bean的时机早,因为后置处理器注入成功后,所有的bean都需要经过已经注入的后置处理器进行拦截,同时后置处理器也分先后顺序,实现PriorityOrdered优先注入,其次实现Ordered,最后什么都没有实现的,这是因为实现PriorityOrdered的后置处理器优先级比较高,这种后置处理器可能需要拦截实现Ordered的后置处理器、什么都没实现的后置处理器,以及普通的bean,简单来说就是实例化任何bean都需要被已经实例化出来的后置处理器进行前后拦截。

等下会拿出和AOP相关的两个后置处理器出来分别介绍,他们分别是AnnotationAwareAspectJAutoProxyCreator和EventListenerMethodProcessor前者实现了Orderd接口,后者什么都没实现,所以再实例化EventListenerMethodProcessor时会被AnnotationAwareAspectJAutoProxyCreator进行拦截

PostProcessorRegistrationDelefate#registerBeanPostProcessors()

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.
   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.
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

   // Next, register the BeanPostProcessors that implement Ordered.
   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.
   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));
}

(4)AbstractBeanFactory#getBean()

@Override
public <T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException {
   return doGetBean(name, requiredType, null, false);
}

(5)AbstractBeanFactory#doGetBean()

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
      @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
	//......
	//前面是一些校验、检查、标记、依赖注入等操作
         // Create bean instance.
         if (mbd.isSingleton()) {
            sharedInstance = getSingleton(beanName, () -> {
               try {
                  return createBean(beanName, mbd, args);
               }
	//......
   }

(6)AbstractAutowireCapableBeanFactory#createBean()

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {

   if (logger.isDebugEnabled()) {
      logger.debug("Creating instance of bean '" + beanName + "'");
   }
   RootBeanDefinition mbdToUse = mbd;

   // Make sure bean class is actually resolved at this point, and
   // clone the bean definition in case of a dynamically resolved Class
   // which cannot be stored in the shared merged bean definition.
   Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
   if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
      mbdToUse = new RootBeanDefinition(mbd);
      mbdToUse.setBeanClass(resolvedClass);
   }

   // Prepare method overrides.
   try {
      mbdToUse.prepareMethodOverrides();
   }
   catch (BeanDefinitionValidationException ex) {
      throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
            beanName, "Validation of method overrides failed", ex);
   }

   try {
      // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
      if (bean != null) {
         return bean;
      }
   }
   catch (Throwable ex) {
      throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
            "BeanPostProcessor before instantiation of bean failed", ex);
   }

   try {
      Object beanInstance = doCreateBean(beanName, mbdToUse, args);
      if (logger.isDebugEnabled()) {
         logger.debug("Finished creating instance of bean '" + beanName + "'");
      }
      return beanInstance;
   }
   catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
      // A previously detected exception with proper bean creation context already,
      // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
      throw ex;
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
   }
}

这里有一个需要注意的地方:Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

这一行代码比较容易忽略,这里面就有后置处理器的拦截工作,但是当注入AnnotationAwareAspectJAutoProxyCreator时,基本上拦截的后置处理器不做任何事情,感兴趣的可以debug看一下,但是当AnnotationAwareAspectJAutoProxyCreator已经初始化好的话,注入在AnnotationAwareAspectJAutoProxyCreator后的bean会被AnnotationAwareAspectJAutoProxyCreator拦截(前置拦截),这里介绍一下EventListenerMethodProcessor,为什么要介绍它,因为该后置处理器会实例化所有的通知类Adviser。仔细看一下…

(7)AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation()

@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
   Object bean = null;
   if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
      // Make sure bean class is actually resolved at this point.
      if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
         Class<?> targetType = determineTargetType(beanName, mbd);
         if (targetType != null) {
            bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
            if (bean != null) {
               bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
            }
         }
      }
      mbd.beforeInstantiationResolved = (bean != null);
   }
   return bean;
}

重点看 bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName)前置处理,其实就是遍历所有已经实例化好的后置处理器进行拦截,除了AnnotationAwareAspectJAutoProxyCreator,其他的一般不做任何处理,debug可以详细查看

(8)AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation()

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
   for (BeanPostProcessor bp : getBeanPostProcessors()) {
      if (bp instanceof InstantiationAwareBeanPostProcessor) {
         InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
         Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
         if (result != null) {
            return result;
         }
      }
   }
   return null;
}

 (9)AbstractAutoProxyCreator#postProcessBeforeInstantiation()

这里是看被AnnotationAwareAspectJAutoProxyCreator拦截处理的逻辑

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
   Object cacheKey = getCacheKey(beanClass, beanName);

   if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
      if (this.advisedBeans.containsKey(cacheKey)) {
         return null;
      }
      if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
         this.advisedBeans.put(cacheKey, Boolean.FALSE);
         return null;
      }
   }

   // Create proxy here if we have a custom TargetSource.
   // Suppresses unnecessary default instantiation of the target bean:
   // The TargetSource will handle target instances in a custom fashion.
   TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
   if (targetSource != null) {
      if (StringUtils.hasLength(beanName)) {
         this.targetSourcedBeans.add(beanName);
      }
      Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
      Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
      this.proxyTypes.put(cacheKey, proxy.getClass());
      return proxy;
   }

   return null;
}

这里比较重要:

①会先将后面的每个bean进行标记,this.advisedBeans.put(cacheKey, Boolean.FALSE);在后面后置处理的时候如果是false就直接返回,不进行代理。

②会实例化Advisor,逻辑在shouldSkip中,看一下

(10)AspectJAutowareAdvisorAutoProxyCreator#shouldSkip()

protected boolean shouldSkip(Class<?> beanClass, String beanName) {
   // TODO: Consider optimization by caching the list of the aspect names
   List<Advisor> candidateAdvisors = findCandidateAdvisors();
   for (Advisor advisor : candidateAdvisors) {
      if (advisor instanceof AspectJPointcutAdvisor &&
            ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
         return true;
      }
   }
   return super.shouldSkip(beanClass, beanName);
}

(11)AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors()

@Override
protected List<Advisor> findCandidateAdvisors() {
   // Add all the Spring advisors found according to superclass rules.
   List<Advisor> advisors = super.findCandidateAdvisors();
   // Build Advisors for all AspectJ aspects in the bean factory.
   if (this.aspectJAdvisorsBuilder != null) {
      advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
   }
   return advisors;
}

(12)BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors()

public List<Advisor> buildAspectJAdvisors() {
   List<String> aspectNames = this.aspectBeanNames;

   if (aspectNames == null) {
      synchronized (this) {
         aspectNames = this.aspectBeanNames;
         if (aspectNames == null) {
            List<Advisor> advisors = new LinkedList<>();
            aspectNames = new LinkedList<>();
            String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                  this.beanFactory, Object.class, true, false);
            for (String beanName : beanNames) {
               if (!isEligibleBean(beanName)) {
                  continue;
               }
               // We must be careful not to instantiate beans eagerly as in this case they
               // would be cached by the Spring container but would not have been weaved.
               Class<?> beanType = this.beanFactory.getType(beanName);
               if (beanType == null) {
                  continue;
               }
               if (this.advisorFactory.isAspect(beanType)) {
                  aspectNames.add(beanName);
                  AspectMetadata amd = new AspectMetadata(beanType, beanName);
                  if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
                     MetadataAwareAspectInstanceFactory factory =
                           new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                     List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                     if (this.beanFactory.isSingleton(beanName)) {
                        this.advisorsCache.put(beanName, classAdvisors);
                     }
                     else {
                        this.aspectFactoryCache.put(beanName, factory);
                     }
                     advisors.addAll(classAdvisors);
                  }
                  else {
                     // Per target or per this.
                     if (this.beanFactory.isSingleton(beanName)) {
                        throw new IllegalArgumentException("Bean with name '" + beanName +
                              "' is a singleton, but aspect instantiation model is not singleton");
                     }
                     MetadataAwareAspectInstanceFactory factory =
                           new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
                     this.aspectFactoryCache.put(beanName, factory);
                     advisors.addAll(this.advisorFactory.getAdvisors(factory));
                  }
               }
            }
            this.aspectBeanNames = aspectNames;
            return advisors;
         }
      }
   }

   if (aspectNames.isEmpty()) {
      return Collections.emptyList();
   }
   List<Advisor> advisors = new LinkedList<>();
   for (String aspectName : aspectNames) {
      List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
      if (cachedAdvisors != null) {
         advisors.addAll(cachedAdvisors);
      }
      else {
         MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
         advisors.addAll(this.advisorFactory.getAdvisors(factory));
      }
   }
   return advisors;
}

这里就是实例化Advisor的详细的逻辑了,看上去很多,但是逻辑也比较简单,意思就是拿到所有的bean的定义信息,然后遍历,判断类型是否是切面类(也就是我们使用了@Aspect注释的类),然后再拿到里面所有的方法进行解析(@Before、@After、@AfterReturning、@AfterThrowing、@Around),后面就不再继续了,这个时候Advisor已经全部放到集合中了。到这里Object bean = resolveBeforeInstantiation(beanName, mbdToUse);就解析完了,我们接着AbstractAutowireCapableBeanFactory#createBean后面的逻辑讲,看到Object beanInstance = doCreateBean(beanName, mbdToUse, args);

(13)AbstractAutowireCapableBeanFactory#doCreateBean

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
      throws BeanCreationException {
//.......
   // Initialize the bean instance.
   Object exposedObject = bean;
   try {
      populateBean(beanName, mbd, instanceWrapper);
      exposedObject = initializeBean(beanName, exposedObject, mbd);
   }
  //......
   return exposedObject;
}

重点看初始化bean,初始化就是给bean进行初始化,同样在初始化前后进行拦截增强

(14)AbstractAutowireCapableBeanFactory#initializeBean()

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
   if (System.getSecurityManager() != null) {
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
         invokeAwareMethods(beanName, bean);
         return null;
      }, getAccessControlContext());
   }
   else {
      invokeAwareMethods(beanName, bean);
   }

   Object wrappedBean = bean;
   if (mbd == null || !mbd.isSynthetic()) {
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }

   try {
      invokeInitMethods(beanName, wrappedBean, mbd);
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            (mbd != null ? mbd.getResourceDescription() : null),
            beanName, "Invocation of init method failed", ex);
   }
   if (mbd == null || !mbd.isSynthetic()) {
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }

   return wrappedBean;
}

invokerInitMethods()这是初始化的方法给bean属性赋值

applyBeanPostProcessorsBeforeInitialization()初始化之前进行拦截增强

applyBeanPostProcessorsAfterInitialization()初始化之后进行拦截

为了节省篇幅,这里就直接介绍相应的业务类的初始化拦截了(Calulator),其实所有的bean的初始化的逻辑流程都是一样的,只是部分细节不一样比如上面分析EventListenerMethodProcessor的时候做了初始化Advisor的工作,后面的操作和普通的bean没什么区别,现在主要介绍差异的部分,当初始化Calculator的时候,这个时候会调用

AnnotationAwareAspectJAutoProxyCreator后置处理器进行增强,生成一个Calculator的动态代理类,这是AOP的核心,一起看看如何生成的

(15)AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization()

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
      throws BeansException {

   Object result = existingBean;
   for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
      Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
      if (current == null) {
         return result;
      }
      result = current;
   }
   return result;
}

这里也会被所有的已经实例化的后置处理器进行拦截,我们重点看AnnotationAwareAspectJAutoProxyCreator,这个时候被拦截的类是Calculator

(16)AbstractAutoProxyCreator#postProcessAfterInitialization()

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
   if (bean != null) {
      Object cacheKey = getCacheKey(bean.getClass(), beanName);
      if (!this.earlyProxyReferences.contains(cacheKey)) {
         return wrapIfNecessary(bean, beanName, cacheKey);
      }
   }
   return bean;
}

wrapIfNecessary()所有被AnnotationAwareAspectJAutoProxyCreator拦截的类都会调用该方法,如果需要对bean进行增强的话,会在这里增强,如果不需要增强的话,会直接返回,看详细逻辑

(17)AbstractAutoProxyCreator#wrapIfNecessay()

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
   if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
      return bean;
   }
   if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
      return bean;
   }
   if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
      this.advisedBeans.put(cacheKey, Boolean.FALSE);
      return bean;
   }

   // Create proxy if we have advice.
   Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
   if (specificInterceptors != DO_NOT_PROXY) {
      this.advisedBeans.put(cacheKey, Boolean.TRUE);
      Object proxy = createProxy(
            bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
      this.proxyTypes.put(cacheKey, proxy.getClass());
      return proxy;
   }

   this.advisedBeans.put(cacheKey, Boolean.FALSE);
   return bean;
}

前面两个部分,在第一次前置处理器的时候已经标记过了,所以不符合需要代理的逻辑,直接return了,而calculator走后面的逻辑,create proxy if we hava advice,如果有advisor则进行代理增强,如果没有,则不进行代理增强,前面分析显然是由advisor,所以就会走createProxy的逻辑

(18)AbstractAutoProxyCreator#createProxy()

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
      @Nullable Object[] specificInterceptors, TargetSource targetSource) {

   if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
      AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
   }

   ProxyFactory proxyFactory = new ProxyFactory();
   proxyFactory.copyFrom(this);

   if (!proxyFactory.isProxyTargetClass()) {
      if (shouldProxyTargetClass(beanClass, beanName)) {
         proxyFactory.setProxyTargetClass(true);
      }
      else {
         evaluateProxyInterfaces(beanClass, proxyFactory);
      }
   }

   Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
   proxyFactory.addAdvisors(advisors);
   proxyFactory.setTargetSource(targetSource);
   customizeProxyFactory(proxyFactory);

   proxyFactory.setFrozen(this.freezeProxy);
   if (advisorsPreFiltered()) {
      proxyFactory.setPreFiltered(true);
   }

   return proxyFactory.getProxy(getProxyClassLoader());
}

(19)ProxyFactory#getProxy()

public Object getProxy(@Nullable ClassLoader classLoader) {
   return createAopProxy().getProxy(classLoader);
}

(20)DefaultAopProxyFactory#createAopProxy()

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
   if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
      Class<?> targetClass = config.getTargetClass();
      if (targetClass == null) {
         throw new AopConfigException("TargetSource cannot determine target class: " +
               "Either an interface or a target is required for proxy creation.");
      }
      if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
         return new JdkDynamicAopProxy(config);
      }
      return new ObjenesisCglibAopProxy(config);
   }
   else {
      return new JdkDynamicAopProxy(config);
   }
}

到这里基本就结束了,会通过cglib或者jdk生成calculator的动态代理,这个时候calculator的div方法就进行了增强了

AOP介绍暂时分享到这里,如有错误欢迎指正,后面有时间再跟大家一起学习,调用calculator的div方法如何调用动态代理的方法,以及拦截连的调用和顺序等

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/111221.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 开关稳压DC—DC降压电路简介

    开关稳压DC—DC降压电路简介  在做数字压力开关项目时,电源输入要求是12V~24V±10%,系统内需要5V和3.3V的电源,这时提供了三个方案从中选择,方案一:使用24V-5V和5V-3.3V的LDO线性稳压芯片。方案二:使用24V-12V,12V-5V,5V-3.3V种LDO线性稳压芯片。方案三:使用24V-5V开关稳压芯片和5V-3.3V的线性稳压芯片。  最后考虑决定使用方案三,方案一中24V-5V的线性稳压芯…

  • break 和 continue 的区别_continue的用法

    break 和 continue 的区别_continue的用法break和continue区别和用法的视频教程:https://ke.qq.com/course/149432?tuin=57912c43有技术问题或者面试方面想学习交流的加我个人微信renlliang2013,本人建了一个微信答疑群,有学习疑问的同学加我拉你进群。想搞清楚break和continue的用法以及区别必须要记住的两件两句话!我们大家先记住一句话:break再循环…

  • JavaScript 对象Array,Map,Set使用

    for(int i = 0 ;i 在说明每个对象的用法之前,首先说明 JavaScript 对象的使用一定要注意浏览器的兼容性问题!尤其是IE的版本!!!! }想查看具体的API请查询 JavaScript 对象 这里面有具体的API介绍!Array,Map,Set使用细则参考上面的JavaScript 对象!下面主要说一下Map!MapJavaScript 的Map

  • Xray的快速使用

    Xray的快速使用快速使用使用基础爬虫爬取并扫描整个网站xraywebscan–basic-crawlerhttp://example.com–html-outputcrawler.html使用HTTP代理进行被动扫描xraywebscan–listen127.0.0.1:7777–html-outputproxy.html设置浏览器http代理为http://127.0.0.1:7777,就可以自动分析代理流量并扫描。如需扫描https流量,请阅读下方文档抓取htt

  • 学习笔记3–车载传感器之毫米波雷达和超声波雷达

    学习笔记3–车载传感器之毫米波雷达和超声波雷达毫米波雷达和超声波雷达。

  • STM32F103C8T6芯片的引脚分布,及注意事项(用于芯片选型)「建议收藏」

    STM32F103C8T6芯片的引脚分布,及注意事项(用于芯片选型)「建议收藏」STM32F103C8T6这款芯片,是我们使用单片机做项目常用到的一款芯片。它具有价格便宜、性能强大、资源齐全等各种优点。我常常使用的是黑金的c8t6核心板,如下:以下将介绍他的资源配置该款芯片各个管脚的功能分配如下(注意:凡是引脚标注有ADC功能的,该引脚都是3.3V耐压,不可接5V信号,否则会使该引脚烧毁或者芯片烧毁)附件为:1.官方c8t6的数据手册(中英文)2….

    2022年10月15日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号