美文网首页《Spring Boot》实战
Spring核心源码深度解析(三) 初始源码

Spring核心源码深度解析(三) 初始源码

作者: 七天0 | 来源:发表于2020-07-08 14:02 被阅读0次

    Spring 源码测试实例

    一个注解配置类,在com包里有一个User接口,两个实现了User接口的方法(提示:从本章开始,建议读者边看边实操)


    image

    测试类,笔者将以AnnotationConfigApplicationContext
    这个注解类作为入口对源码进行深度分析


    image

    Spring 源码分析

    进入笔者将以AnnotationConfigApplicationContext的构造方法


    image

    注意细节AnnotationConfigApplicationContext继承了GenericApplicationContext


    image
    所以会优先执行GenericApplicationContext的默认构造器,并且会创造一个叫DefaultListableBeanFactory的这么个类,
    image
    这个类分量很大,是Spring的核心类,我们点开DefaultListableBeanFactory这个类, image

    我们一步一步向上跟踪会发现它实现了BeanFactory,所以这就我们一直说的Bean工厂、Bean工厂,实际上Bean工厂也就是在这个时候就创建了,当然这个类还要其他重要的功能,笔者暂时放一放,咱们继续往下走,执行完父类的构造器后,现在开始执行自己的构造器了

    public AnnotationConfigApplicationContext() {   
        //这个reader顾名思义是一个读取器,而且十分重要,稍后会说明为什么重要  
        this.reader = new AnnotatedBeanDefinitionReader(this);  
        //这个scanner说实话没有什么卵用,因为在spring内部自己new了一个扫描器,而不是用的这个对象,而这个类是交给程序员手动获取的,基本用不到  
        this.scanner = new ClassPathBeanDefinitionScanner(this);
        }   
    
    如上图所示:AnnotationConfigApplicationContext构造器创建了一个读取器,一个扫描器,而这个scanner为什么由上述注释所写的后期我们在扫描的时候证明。进入this.reader=new AnnotatedBeanDefinitionReader(this); 这行代码调入 image

    然后构造器相互调用最终调用这个构造器

    image

    进入AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
    里面又是委托模式,继续渗入registerAnnotationConfigProcessors(registry, null);
    最终进入核心方法registerAnnotationConfigProcessors()这个方法大概就做了两件事情,获取之前创建的DefaultListableBeanFactory,然后往里面装一些工具组件,包含排序组件、转换器组件、以及4个特别特别重要的后置处理器。分别是

    
    1、ConfigurationClassPostProcessor
    2、AutowiredAnnotationBeanPostProcessor
    3、CommonAnnotationBeanPostProcessor
    4、EventListenerMethodProcessor
    

    在registerAnnotationConfigProcessors()涉及到Spring后置处理器和BeanDefinition,下面会进行简要分析

    Spring后置处理器

    什么是后置处理器,笔者这里对Spring其中一个顶层的后置处理器进行详细说明


    image

    看了上面的注释,读者可能还是比较懵逼,我们在实践一下


    image 我们实现了BeanFactoryPostProcessor拿到了ConfigurableListableBeanFactory,然后我们从工厂可以获取某一个类的BeanDefinition(注意:很多小伙伴一个有一个误区,不知道什么是对象什么是Bean,笔者认为Bean一定是对象,对象不一定是Bean,而对象成为Bean的条件就是完成Spring的整体生命周期),拿到从工厂获取的BeanDefinition,是不是就可以进行修改这个BeanDefinition,再结合笔者上文后置处理器的注释,相信这个时候读者应该对后置处理器有一定初步的认识,当然这个时候小伙伴们可能就要问了,我拿到BeanDefinition有什么用?看下图, image

    这里并没有对Spring Bean流程详细介绍,只是对整体流程描述了大概。如果还是不明白我们在后面会详细说明后置处理器的作用。

    BeanDefinition

    在think in java的作者提出,一切皆为对象,一切皆可抽象,而BeanDefinition正是Spring抽象设计的精髓,回到上文笔者强调Bean和对象不是同一个概念,Spring认为仅仅是java自带的对象是不能满足于我所需求的,就好比单例、Lazy等一些特性无法满足,所以Spring定义一个BeanDefinition作为对象的抽象,来实现对象的抽象,(当然BeanDefinition的分量很高,笔者在后面会更详细的介绍它具体的作用)明白这点后我们回到代码:

    public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
          BeanDefinitionRegistry registry, @Nullable Object source) {
    
        //从注册器获取beanFactory
        DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
        if (beanFactory != null) {
          //这里是判断beanFactory有没有排序的工具
          if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
            beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
          }
          //这里是判断beanFactory有没有转换器
          if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
            beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
          }
        }
        //之后你会看到很多BeanDefinitionHolder,这个BeanDefinitionHolder其实没什么作用,就是一个
        //封装了BeanDefinition的map,而BeanDefinition是对spring将要实例化对象的一个缓存,
        //类似于对象的class,只是功能比class更丰富
        Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
        //重点来了,这里涉及到了一个概念叫BeanFactoryPostProcessor,详细看接口
        //registerPostProcessor这个方法就是将RootBeanDefinition放到工厂的map对象去
        if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
          RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
          def.setSource(source);
          beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
        }
    
        //下面是注册五个类,但有一个类会被忽略,所以总共只注册了五个类
        if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
          RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
          def.setSource(source);
          beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
        }
    
        // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
        if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
          RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
          def.setSource(source);
          beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
        }
    
        // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
        if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
          RootBeanDefinition def = new RootBeanDefinition();
          try {
            def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
                AnnotationConfigUtils.class.getClassLoader()));
          }
          catch (ClassNotFoundException ex) {
            throw new IllegalStateException(
                "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
          }
          def.setSource(source);
          beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
        }
    
        if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
          RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
          def.setSource(source);
          beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
        }
    
        if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
          RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
          def.setSource(source);
          beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
        }
    
        return beanDefs;
      }
    

    这里其实就是获取前面创建的工厂,然后向工厂装一些组件,目的就是初始化工厂,然后再为工厂创建Spring自定义的后置处理器作为BeanDefinition存起来,然后返回,这是我们的this已经执行完毕,回到这个图。

    image

    咱们再看一遍注释,相信读者大致能理解
    我们再看register方法->this.reader.register(componentClasses);->registerBean(componentClass);->doRegisterBean(beanClass, null, null, null);

    <T>  void doRegisterBean(Class<T> beanClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
          @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
        //这里可以看到使用AnnotatedGenericBeanDefinition去创建的 后面会通过这个类的父接口去做一些判断
        //此外在这个创建注解BD的时候就对内部的元注解进行初始化,自己有标识了注解
        AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
        if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
          return;
        }
        abd.setInstanceSupplier(instanceSupplier);
        //获取作用域元数据
        ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
        abd.setScope(scopeMetadata.getScopeName());
        String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
        //这里是对Config配置类进行注解信息的设置,Lazy,Primary,DependsOn等等
        AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
        if (qualifiers != null) {
          for (Class<? extends Annotation> qualifier : qualifiers) {
            if (Primary.class == qualifier) {
              abd.setPrimary(true);
            }
            else if (Lazy.class == qualifier) {
              abd.setLazyInit(true);
            }
            else {
              abd.addQualifier(new AutowireCandidateQualifier(qualifier));
            }
          }
        }
        for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
          customizer.customize(abd);
        }
        BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
        definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
        //将bd注册到我们的BeanFactory去
        BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
      }
    

    其实我们可以看到核心代码就是最下面一句, BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);将我们的配置类或普通类注册到BeanDefinitionMap集合里。而前面只是做一些判断,比如是不是Lazy,Primary,DependsOn,有没有Supplier等

    深度分析Spring核心方法refresh()

    refresh()目录
    //这个方法没什么用,里面都是一些系统环境设置
    prepareRefresh();
    // 这里只是将beanFactory拿出来
    ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    // 对beanFactory添加一些处理器,并设置一些属性
    prepareBeanFactory(beanFactory);
    // 空方法
    postProcessBeanFactory(beanFactory);
    // 这里是执行实现了BeanFactoryPostProcessor这个接口的子类
    // 重点就是spring自己的一个类
    // 秒扫出要实例化的类,放进工厂的beanDef里面,这里只是放的bd并不是真正的实例化对象invokeBeanFactoryPostProcessors(beanFactory);
    //注册BeanPostProcessor
    registerBeanPostProcessors(beanFactory);
    // Initialize message source for this 
    context.initMessageSource();
    // 创建ApplicationEventMulticaster这么一个类initApplicationEventMulticaster();
    //空方法  
    onRefresh();
    // 注册监听器
    registerListeners();
    //完成对bean的创建finishBeanFactoryInitialization(beanFactory);
    // publish corresponding event.
    finishRefresh();
    

    我们可以看到Spring在refresh方法里面做了很多很多的事情,我们逐步分析:

    prepareRefresh():这个方法并不用太关注,这是Spring记录一些系统日期、日志之类的,我们直接跳过。

    obtainFreshBeanFactory():这个方法只是将创建的工厂拿出来给后续的方法作为参数利用

    image

    prepareBeanFactory():

    
    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // 这里是对beanFactory设置一些工具类,后面用到再说,先跳过
        beanFactory.setBeanClassLoader(getClassLoader());
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    
        // 添加一个ApplicationContextAwareProcessor后置处理器
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        //设置一些需要忽略的类,避免重复,这里就是避免从面部传进这些class影响Spring内部操作
        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
        beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
    
    

    看这句代码,beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));、进入ApplicationContextAwareProcessor 找到下面代码


    image

    可以看到里面有大量的回调接口。如果没搞明白我们写了例子


    image image

    可以看出,我们可以通过回调拿到Spring内部的对象,这里可以结合再一个实例,单例对象的属性注入原型对象,就需要这种方式解决,而这个对象那里来的呢,咱们回到源码:

      //解决依赖注入来源问题
        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);
    
        // 注册一个用来销毁Bean的后置处理器
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
    
        // Detect a LoadTimeWeaver and prepare for weaving, if found.
        if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
          beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
          // Set a temporary ClassLoader for type matching.
          beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }
    
        // Register default environment beans.
        if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
          beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
        }
        if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
          beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
        }
        if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
          beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
        }
      }
    

    这里就是Spring内部注册的对象,这里涉及到一个数据源的问题,我们会在依赖注入的环节单独详细说明笔者暂且可以认为这些对象没有经过Spring的生命周期,但可以提供依赖注入。

    postProcessBeanFactory()

    image

    空壳方法,这里猜测是Spring为自己预留的拓展功能。接下来的方法较为重要,笔者打算单独开一章节详细分析

    本小节总结:
    1、创建一个工厂 this.beanFactory = new DefaultListableBeanFactory();
    2、创建一个读取器 this.reader = new AnnotatedBeanDefinitionReader(this);
    3、对beanFactory添加一些组件工具,添加4个后置处理器
    4、通过之前创建的读取器把传进来的类转换为BeanDefinition注册到工厂里。

    5、Spring在自己内部设置了一些数据源信息比如ApplicationContext、Resourse等

    6、添加了一个ApplicationContextAwareProcessor后置处理器提供Aware回调

    7、忽略一些Spring内部关键的类,防止外部修改或影响了Spring内部的核心类

    相关文章

      网友评论

        本文标题:Spring核心源码深度解析(三) 初始源码

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