美文网首页
Spring 源码详解AOP (三)

Spring 源码详解AOP (三)

作者: Rogge666 | 来源:发表于2022-02-27 00:38 被阅读0次

    书接上回,在启动类或者配置类上使用@EnableAspectJAutoProxy开启AOP
    容器会将AspectJAutoProxyRegistrar注入

    image.png
    由于AspectJAutoProxyRegistrar实现了ImportBeanDefinitionRegistrar接口,所以在注册时会调用registerBeanDefinitions来注册对应的Bean
    image.png
    可以看到registerBeanDefinitions最后注册的是AnnotationAwareAspectJAutoProxyCreator
    image.png
    实际上AnnotationAwareAspectJAutoProxyCreator为Bean的后置处理器,由Spring 源码详解Bean创建 (二)知道在Bean创建完成初始化的前后会执行所有BeanPostProcessor的前置处理(postProcessBeforeInstantiation)和后置处理(postProcessAfterInitialization)
    所以在Bean的初始化
    image.png
    接下来举个例子介绍AOP的完整流程,创建BusService中divide方法为切点,看看AOP是如何将TestAspectJAnnotationProcess的方法织入到BusService中
    image.png image.png
    image.png

    直接从BusService完成创建填充属性后开始初始化开始


    image.png
    AnnotationAwareAspectJAutoProxyCreator前置处理直接返回不做任何处理

    AnnotationAwareAspectJAutoProxyCreator开始处理后置


    image.png
    image.png
    image.png
    image.png
    image.png
    public List<Advisor> buildAspectJAdvisors() {
        List<String> aspectNames = this.aspectBeanNames;
    
        if (aspectNames == null) {
            synchronized (this) {
                aspectNames = this.aspectBeanNames;
                if (aspectNames == null) {
                    List<Advisor> advisors = new ArrayList<>();
                    aspectNames = new ArrayList<>();
                    //查出容器中所有的BeanName
                    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, false);
                        if (beanType == null) {
                            continue;
                        }
                        //将带有@Aspect注解的Bean筛选出来
                        if (this.advisorFactory.isAspect(beanType)) {
                            aspectNames.add(beanName);
                            AspectMetadata amd = new AspectMetadata(beanType, beanName);
                            if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
                                //创建处理带有@Aspect类的Bean工厂
                                MetadataAwareAspectInstanceFactory factory =
                                        new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                                //创建切面Advisor对象
                                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 ArrayList<>();
        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;
    }
    
    image.png
    image.png
    image.png
    image.png
    image.png
    image.png
    image.png
    image.png

    如下图创建完毕的代理类回调callback_0为DynamicAdvisedInterceptor类型


    image.png
    IOC容器创建完成,执行业务方法,进入切点
    image.png
    进入CGLIB回调
    image.png
    image.png
    image.png
    image.png
    image.png
    image.png
    image.png

    其他几个通知节点不一一介绍,大家有兴趣可以看看源码,至此AOP代理创建以及运行时执行解析流程全部结束。

    相关文章

      网友评论

          本文标题:Spring 源码详解AOP (三)

          本文链接:https://www.haomeiwen.com/subject/lgrcrrtx.html