专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

Spring IoC 初始化之先发五虎

121_1.png

Spring IoC 初始化之先发五虎

  接上文所述,源码分析来到了 AnnotationConfigApplicationContext() 方法中的 new AnnotatedBeanDefinitionReader(this) 方法。下面就从 new AnnotatedBeanDefinitionReader(this)这一行代码开始。首先解释this,这里this指的是当前类,也即 AnnotationConfigApplicationContext。

1. 代码入口

/**
 * BeanDefinitionRegistry是通过AnnotatedBeanDefinitionReader构造方法中的this传进来
 * 这里说明 AnnotationConfigApplicationContext 就是 BeanDefinitionRegistry。
 */
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
 this(registry, getOrCreateEnvironment(registry)); } 
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    Assert.notNull(environment, "Environment must not be null");
    this.registry = registry;
    this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
 /** * 通过AnnotationConfigUtils.registerAnnotationConfigProcessors() * 获取所有BeanPostProcessor 的bean */ AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); } 

  隆重介绍一下,在AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);方法中会将五个内置的对象通过一些列方法注册到IoC容器中。这五个对象在IoC中的地位举足轻重。我称之为:先发五虎

   registerAnnotationConfigProcessors 中通过给定的注册器,注册所有注解相关的后置处理器。

public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
    registerAnnotationConfigProcessors(registry, null);
}

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
        BeanDefinitionRegistry registry, @Nullable Object source) {
    /**
     * 通过registry生成一个beanFactory
 */
 DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry); if (beanFactory != null) { if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) { /** * 添加AnnotationAwareOrderComparator类的对象,注意去排序 */ beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); } if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) { /** * 提供处理延迟加载的功能 */ beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); } } Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8); /** 注册BeanDefinition,到Map中*/ if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) { /** * ConfigurationClassPostProcessor 的类型是 BeanDefinitionRegistryPostProcessor * BeanDefinitionRegistryPostProcessor 实现的是 BeanFactoryPostProcessor 接口 * * RootBeanDefinition 是 BeanDefinition的子类 */ 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; } 

  在上述的方法中,都通过 registerPostProcessor 中调用 registerBeanDefinition 方法将 definition 放置到 Map当中。可以看到放到Map中的这个对象都是Spring内部自己定义的。这说明在容器初始化的时候,加载程序员自定义的Bean 的时候,已经有一部分对象被加载到容器中了,通过这些对象来完成后续其他对象的加载。

/**
 * 往BeanDefinitionMap中注册
 * @param registry
 * @param definition
 * @param beanName * @return 返回一个 BeanDefinitionHolder 对象 */ private static BeanDefinitionHolder registerPostProcessor( BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) { definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); /** * 将bean放入Map中 */ registry.registerBeanDefinition(beanName, definition); // 返回 BeanDefinitionHolder return new BeanDefinitionHolder(definition, beanName); } 

  关于 registerBeanDefinition 后面在Spring Bean 的注册中会详细介绍,这里暂不做介绍。但是这看到有一个 BeanDefinitionHolder 对象。从上述代码来看 BeanDefinitionHolder 是对 BeanDefinitionbeanName 的封装。

   BeanDefinition 是 Spring 中对 基于注解,或者通过xml方式定义的Bean的封装。这里只做概念上的描述,后续会对 BeanDefinition 有一个系统性的认识。

时序图

121_2.png

  在上述的时序图中,提到有一个极其重要的过程,在此过程中向IoC容器中的beanDefinitionMap中put了 5个Spring内置的对象,这五个对象对应的Spring 的Bean的描述文件为RootBeanDefinition。

  这些类的实现方式都是对Spring后置处理器的应用,关于Spring的扩展点以及扩展点的应用,在以后都会介绍到。 这里我们先抓住主要矛盾,容器的初始化。这5个对象在Spring中对应的常量,对应Spring中的类,以及注解。其对应关系如下:

常量 对应的BeanPostProcessor 对应的注解
CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME ConfigurationClassPostProcessor @Configuration
AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME AutowiredAnnotationBeanPostProcessor @AutoWired
REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME RequiredAnnotationBeanPostProcessor @Required
COMMON_ANNOTATION_PROCESSOR_BEAN_NAME CommonAnnotationBeanPostProcessor @PostConstruct @PreDestroy
EVENT_LISTENER_PROCESSOR_BEAN_NAME EventListenerMethodProcessor @EventListener
EVENT_LISTENER_FACTORY_BEAN_NAME EventListenerFactory EventListener

  这里要对ConfigurationClassPostProcessor这个类要足够的重视,因为该类对应着对注解@Configuration的处理。在这里要记住 这个类及其的重要,后面会多次提到这个类。

2.容器形成图

121_3.png 图1

  在上一篇文章的最后在类继承关系的角度,分析了容器初始化图: 121_4.png   通过一个new 关键字引发的一系列连锁反应,需要完成如图二所示图中对象的初始化。

  在图一中则更为细节的介绍了这些对象初始化的时候,会做一些什么事。会对IoC 容器做一些什么样的补充。以级容器中对象的变化。

3.总结

  至此,AnnotationConfigApplicationContext(Class<?>... componentClasses)构造方法中对应的this()方法部分已经,全部结束咯…容器对应的也渐渐丰满了起来。当然,也有很多的问题没有去解决,本着抓住主要的矛盾的思路,对没有说明的问题做一个记录,后续会慢慢补齐:

  • BeanDefinition
  • BeanDefinitionHolder
  • Spring 扩展点值 BeanPostProcessor

本文使用 mdnice 排版

文章永久链接:https://tech.souyunku.com/28085

未经允许不得转载:搜云库技术团队 » Spring IoC 初始化之先发五虎

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们