「推荐收藏!」【Spring源码探究】(一)IOC容器初始化🏅彻底让你明白运行原理和源码流程

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 「推荐收藏!」【Spring源码探究】(一)IOC容器初始化🏅彻底让你明白运行原理和源码流程

框架体系文章


  • IOC容器初始化🏅彻底让你明白运行原理和源码流程
  • Bean的生命周期🏅彻底让你明白运行原理和源码流程
  • AOP代理初始化🏅彻底让你明白运行原理和源码流程




IOC系列文章


  • IOC细节之invokeBeanFactoryPostProcessors🏅彻底让你明白运行原理和源码流程
  • IOC细节之registerBeanPostProcessors🏅彻底让你明白运行原理和源码流程
  • IOC细节之finishBeanFactoryInitialization及解决循环依赖🏅彻底让你明白运行原理和源码流




前言介绍


本篇文章篇幅较大,希望读者可以慢慢阅读,建议收藏,分多次阅读学习。


  • 学习源码的过程当中,有几点建议:


  • 一定要学会抓重点,归纳核心类、核心方法、核心步骤;
  • 分析源码我们不需要太过于纠结细节,不然,这个源码最起码得分析月才能分析完
  • 主要的目的是分析整个容器初始化过程,怎么初始化bean,怎么设置动态代理;我们主要学习的是他们的思想,以及代码中运用到的设计模式





容器框架重要对象


  • BeanFactory:用于访问容器中bean的接口,使用的是工厂模式,重点注意DefaultListableBeanFactory,是贯穿的整个容器的基本工厂类。
  • BeanDefinition:BeanDefinition是bean在Spring中的描述,先读取到bean的各种元素,然后利用BeanDefinition去初始化bean,是spring从起管理bean对象的数据模型。
  • BeanDefinitionRegistry接口:注册bean定义到Spring容器中,与BeanFactory接口相对应,主要针对于Bean的注册,BeanFactory主要针对于bean对象的管理。
  • BeanFactoryPostProcessor接口:bean工厂后置处理器,该接口的作用主要是提供扩展点,用于各种bean定义的注册和实例化等,比较需要主要关注ConfigurationClassPostProcessor该类;
  • BeanPostProcessor接口:bean的后置处理器,该接口提供的扩展点,用于初始化bean,以及初始化完成后的各种扩展





IOC容器初始化的大致流程


  • 首先读取BeanDefinition放到容器中。
  • 通过BeanFactoryPostProcessor对象的扩展
  • 通过BeanPostProcessor对象的扩展
  • 然后根据BeanDefinition去初始化bean。
  • 最后实际进行初始化然后保存到容器中。


image.png

image.png




来实现各种不同的功能;IOC容器初始化大致的一个流程,主要是看AnnotationConfigApplicationContextrefresh




AnnotationConfigApplicationContext构造器分析


传入配置类的构造函数

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    //初始化容器,创建bean工厂,加载各种内部重要类的bean定义,用于初始化我们或者其他引入类
    this();
    //注册我们配置类的bean定义,初始化容器,从这个类开始
    register(componentClasses);
    //准备工作做好后,开始初始化容器
    refresh();
}
复制代码



先看下this()这一行代码


AnnotatedBeanDefinitionReader:主要用于读取相关内部的Spring容器的Bean对象。

public AnnotationConfigApplicationContext() {
    //初始化读取bean定义的读取器,完成Spring内部bean定义的注册
    this.reader = new AnnotatedBeanDefinitionReader(this);
    //初始化一个类扫描器,其实这个方法进来,是没有用到这个扫描器的
    this.scanner = new ClassPathBeanDefinitionScanner(this);
}
复制代码

从上面创建bean定义读取器,看下构造方法

//从上面创建bean定义读取器,看下构造方法
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");
    //把ApplicationContext对象赋值给bean定义读取器
    this.registry = registry;
    this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
    //主要是看这个方法,注册Spring内部重要的bean定义
    AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
复制代码


到这里this(),这个方法流程就过完了,主要就是注册spring内部重要的bean定义,来看下register(componentClasses)方法

//此目的主要针对于上面注册的reader进行注册相关的bean
public void register(Class<?>... annotatedClasses) {
    Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
    //使用上面初始化的bean定义读取器,去注册我们配置类的bean定义
    this.reader.register(annotatedClasses);
}
//遍历去注册传入进来的注解相关的Bean对象
public void register(Class<?>... annotatedClasses) {
    for (Class<?> annotatedClass : annotatedClasses) {
        registerBean(annotatedClass);
    }
}
// 
public void registerBean(Class<?> annotatedClass) {
    doRegisterBean(annotatedClass, null, null, null);
}
//注册bean定义
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
        @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
        @Nullable BeanDefinitionCustomizer[] customizers) {
    //根据配置类创建一个bean定义
    AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
    if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
        return;
    }
    abd.setInstanceSupplier(supplier);
    //解析bean的作用域,如果没有设置,则默认是单例
    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
    abd.setScope(scopeMetadata.getScopeName());
  // 创建bean对象的bean名称
    String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
    //解析该bean是否有Lazy,Primary,DependsOn,Description等注解,有则填充进去
    AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
    if (qualifiers != null) {
        for (Class<? extends Annotation> qualifier : qualifiers) {
      //判断是否是Primary
            if (Primary.class == qualifier) {
                abd.setPrimary(true);
            }
      // 判断是否属于懒惰加载
            else if (Lazy.class == qualifier) {
                abd.setLazyInit(true);
            }
            else {
                abd.addQualifier(new AutowireCandidateQualifier(qualifier));
            }
        }
    }
    if (customizers != null) {
        for (BeanDefinitionCustomizer customizer : customizers) {
            customizer.customize(abd);
        }
    }
  // 构建BeanDefinitionHolder对象去引用对象
    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
    definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
    //最后把该bean定义注册到Bean工厂中去
    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
复制代码

register(componentClasses),方法到此结束,然后我们分析refresh();方法,该方法初始化了IOC容器。

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        //设置容器状态,准备刷新容器
        prepareRefresh();
        //获取到容器的bean工厂
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        //填充bean工厂的各种属性
        prepareBeanFactory(beanFactory);
        try {
            //留给子类实现,我们看的AnnotationConfigApplicationContext继承了GenericApplicationContext,该类主要是注册了ServletContextAwareProcessor
            postProcessBeanFactory(beanFactory);
            //主要调用bean工厂的后置处理器,把我们的类,注册成bean定义
            invokeBeanFactoryPostProcessors(beanFactory);
        // 注册 BeanPostProcessor 的实现类
         // 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
         // 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化
            registerBeanPostProcessors(beanFactory);
            //初始化国际化资源(这个方法不重要)
            initMessageSource();
            //Spring事件相关,主要是创建一个事件多播器
            initApplicationEventMulticaster();
            //留给子类实现
            onRefresh();
            //把我们的事件注册到容器中
            registerListeners();
            //实例化我们需要的bean,放入IOC容器
            finishBeanFactoryInitialization(beanFactory);
            //完成容器IOC容器初始化,并且发布初始化完成事件
            finishRefresh();
        }
        catch (BeansException ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                        "cancelling refresh attempt: " + ex);
            }
            destroyBeans();
            cancelRefresh(ex);
            throw ex;
        }
        finally {
            resetCommonCaches();
        }
    }
}
复制代码




分析主要的步骤


  1. 首先 prepareRefresh():方法主要是为容器设置一个状态(准备工作,记录下容器的启动时间、标记“已启动”状态、处理配置文件中的占位符)
  2. 然后接下来是获取相应的工厂类,AnnotationConfigApplicationContext主要是获取到DefaultListableBeanFactory,但是如果是XML方式,会在该方法去加载bean定义,我们不分析这种方式
  • 这步比较关键,这步完成后,配置文件/配置类就会解析成一个Bean定义,注册到 BeanFactory 中,
  • 这里说的Bean还没有初始化,只是配置信息都提取出来了,
  • 注册也只是将这些信息都保存到了注册中心(说到底核心是一个 beanName-> beanDefinition 的 map)




prepareRefresh() 创建容器前的准备工作


protected void prepareRefresh() {
   // 记录启动时间,
   // 将 active 属性设置为 true,closed 属性设置为 false,它们都是 AtomicBoolean 类型
   this.startupDate = System.currentTimeMillis();
   this.closed.set(false);
   this.active.set(true);
   if (logger.isInfoEnabled()) {
      logger.info("Refreshing " + this);
   }
   // Initialize any placeholder property sources in the context environment
   initPropertySources();
   // 校验 xml 配置文件
   getEnvironment().validateRequiredProperties();
   this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
}
复制代码



obtainFreshBeanFactory() 创建 Bean 容器,加载并注册 Bean IoC初始化里面最重要的部分。

关键是以下几步:

  • 初始化BeanFactory
  • 加载Bean
  • 注册Bean

注意:这步完成后,Bean 并没有完成初始化,实际的实例并没有被创建。

AbstractApplicationContext#obtainFreshBeanFactory()

protected ConfigurableListableBeanFactory obtainFreshBeanFactory(){
        // 关闭旧的 BeanFactory (如果有),创建新的 BeanFactory,加载 Bean 定义、注册 Bean 等等
        refreshBeanFactory();
        // 返回上一步刚刚创建的BeanFactory
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        if (logger.isDebugEnabled()) {
            logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
        }
        return beanFactory;
    }
复制代码



AbstractRefreshableApplicationContext#refreshBeanFactory()

protected final void refreshBeanFactory() throws BeansException {
        // 如果 ApplicationContext 已经加载过 BeanFactory,销毁所有的Bean,关闭BeanFactory
        // 注意点:应用中BeanFactory是可以有多个的,这里可不是说全局是否有BeanFactory
        // 而是说当前的ApplicationContext有没有BeanFactory!
        if (hasBeanFactory()) {
            destroyBeans();
            closeBeanFactory();
        }
        try {
            // 初始化一个 DefaultListableBeanFactory
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            // 用于 BeanFactory 的序列化,一般人应该用不到吧...
            beanFactory.setSerializationId(getId());
            // 下面是两个重点方法
            // 设置 BeanFactory 的两个重要属性
            // 是否允许 Bean 覆盖、是否允许循环引用
            customizeBeanFactory(beanFactory);
            // 加载BeanDefinition到BeanFactory  单独拉出来讲
            loadBeanDefinitions(beanFactory);
            synchronized (this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        }
        catch (IOException ex) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
        }
   }
复制代码



可以感觉到一个设计思路,ApplicationContext 继承自 BeanFactory,但是它不应该被理解为 BeanFactory 的实现类,而是说其内部持有一个实例化的 BeanFactory(DefaultListableBeanFactory)。以后所有的 BeanFactory 相关的操作其实是委托给这个实例来处理的。

customizeBeanFactory

protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
        if (this.allowBeanDefinitionOverriding != null) {
            beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
        }
        if (this.allowCircularReferences != null) {
            beanFactory.setAllowCircularReferences(this.allowCircularReferences);
        }
    }
复制代码

BeanDefinition 的覆盖问题可能会有开发者碰到这个坑,就是在配置文件中定义 bean 时使用了相同的 id 或 name。


默认情况下,allowBeanDefinitionOverriding 属性为 null(Boolean类型),如果在同一配置文件中重复了,会抛错,但是如果不是同一配置文件中,会发生覆盖

  • 循环引用也很好理解:A 依赖 B,而 B 依赖 A。或 A 依赖 B,B 依赖 C,而 C 依赖 A。
  • 默认情况下,Spring 允许循环依赖,当然如果你在 A 的构造方法中依赖 B,在 B 的构造方法中依赖 A 是不行的



loadBeanDefinitions(beanFactory) 加载BeanDefinition

/**
     * Load bean definitions into the given bean factory, typically through
     * delegating to one or more bean definition readers.
     * @param beanFactory the bean factory to load bean definitions into
     * @throws BeansException if parsing of the bean definitions failed
     * @throws IOException if loading of bean definition files failed
     * @see org.springframework.beans.factory.support.PropertiesBeanDefinitionReader
     * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
     */
    protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
            throws BeansException, IOException;
复制代码

ClassPathXmlApplicationContext 是按照解析XML的加载方式。看javadoc的描述,是通过XmlBeanDefinitionReader来载入Bean Definitions。

/**
     * Loads the bean definitions via an XmlBeanDefinitionReader.
     * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
     * @see #initBeanDefinitionReader
     * @see #loadBeanDefinitions
     */
    @Override
    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
        // Create a new XmlBeanDefinitionReader for the given BeanFactory.
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
        // Configure the bean definition reader with this context's
        // resource loading environment.
        beanDefinitionReader.setEnvironment(this.getEnvironment());
        beanDefinitionReader.setResourceLoader(this);
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
        // Allow a subclass to provide custom initialization of the reader,
        // 初始化Reader 不重要,看下这个方法的javadoc就很好理解了
        initBeanDefinitionReader(beanDefinitionReader);
        // 真正重要的步骤!!
        // 用Reader去加载XML配置
        loadBeanDefinitions(beanDefinitionReader);
    }
复制代码



loadBeanDefinitions(beanDefinitionReader)

/**
     * Load the bean definitions with the given XmlBeanDefinitionReader.
     * 看这句注释:this method is just supposed to load and/or register bean definitions.
     */
    protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
        Resource[] configResources = getConfigResources();
        if (configResources != null) {
            reader.loadBeanDefinitions(configResources);
        }
        String[] configLocations = getConfigLocations();
        if (configLocations != null) {
            // 这个分支,通过路径名去获取Resource,会和上面的方法殊途同归
            reader.loadBeanDefinitions(configLocations);
        }
    }
复制代码



AbstractBeanDefinitionReader#loadBeanDefinitions(Resource... resources)

@Override
    public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
        Assert.notNull(resources, "Resource array must not be null");
        int counter = 0;
        for (Resource resource : resources) {
            // 遍历解析XML文件,加载 BeanDefinition
            counter += loadBeanDefinitions(resource);
        }
        return counter;
    }
复制代码



接下去的源码不细讲,这里载入分为两大步,


  1. 就是通过调用XML的解析器获取到 document 对象,完成通用XML解析;
  2. 就是按照Spring的Bean规则进行解析
  • Spring的Bean规则进行解析这个过程是BeanDefinitionDocumentReader来实现的,里面包含了各种Spring Bean定义规则的处理。
  • 这里我觉得核心知识点就是Spring Bean规则的解析,简单点来说,里面包含了我们在XML配置的那些信息,怎么解析成容器中 BeanDefinition的规则和步骤。这部分由于和主要流程关系不大。
  • 在这因为Spring 的 Bean配置方式有很多,解析配置信息到BeanDefinition的实现方式也有很多,XML又是现在少用的方式,所以关于XML中的Spring Bean规则的解析的详细源码就先略过了。



我们来看下prepareBeanFactory(beanFactory)这个方法

设置 BeanFactory的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    //设置类加载器,为当前应用的application的类加载器
    beanFactory.setBeanClassLoader(getClassLoader());
    //为bean工厂设置一个标准的SPEL表达式解析器
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    //为bean工厂设置一个资源编辑器,为了后面bean初始化时,给bean对象赋值
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    //忽略以下接口的bean,这些bean都有set方法,不会对这些bean进行属性赋值
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    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,就是从这里注册的获取到的
    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));
    //处理AOP的后置处理器
    if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
    //注册bean工厂的环境属性
    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());
    }
}
复制代码



接下来分析postProcessBeanFactory(beanFactory);


  • 这里需要知道BeanFactoryPostProcessor 这个知识点,Bean 如果实现了此接口, 那么在容器初始化以后,Spring 会负责调用里面的 postProcessBeanFactory 方法
  • 提供给子类的扩展点,到这里的时候,所有的Bean都加载、注册完成了,但是都还没有初始化。
  • 具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事。
  • 该方法没有做实际的事情,主要是把ServletContextAwareProcessor后置处理器,给注册进去。
  • 实现ServletContextAware接口获取上下文容器,就是从这里注入的。
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    if (this.servletContext != null) {
        beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext));
        beanFactory.ignoreDependencyInterface(ServletContextAware.class);
    }
    WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
    WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext);
}
复制代码



接下来分析invokeBeanFactoryPostProcessors(beanFactory);

调用BeanFactoryPostProcessor实现类 postProcessBeanFactory(factory) 方法

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    //获取FactoryPostProcessors,Spring内置的和自己设置的,然后供接下来的调用
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
    if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
}
public static void invokeBeanFactoryPostProcessors(
        ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    //放入已经被处理过的bean
    Set<String> processedBeans = new HashSet<>();
    //当前bean工厂是否实现了BeanDefinitionRegistry,如果有的话,则可以注册bean定义
    if (beanFactory instanceof BeanDefinitionRegistry) {
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
        List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
        //循环我们传入的bean工厂后置处理器,并加入到处理器集合中
        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryProcessor =
                        (BeanDefinitionRegistryPostProcessor) postProcessor;
                registryProcessor.postProcessBeanDefinitionRegistry(registry);
                registryProcessors.add(registryProcessor);
            }
            else {
                regularPostProcessors.add(postProcessor);
            }
        }
        //保存当前实例化的BeanDefinitionRegistryPostProcessor
        List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
        //从bean工厂中获取到继承了BeanDefinitionRegistryPostProcessor的bean
        String[] postProcessorNames =
              beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
            //实例化优先级最高的BeanDefinitionRegistryPostProcessor
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                //实例化出BeanDefinitionRegistryPostProcessor的类,我们正常初始化这里只有ConfigurationClassPostProcessor
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        //对实例化出来的BeanDefinitionRegistryPostProcessor进行排序
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        //把实例化出来的BeanDefinitionRegistryPostProcessor添加进总的集合中供后面调用
        registryProcessors.addAll(currentRegistryProcessors);
        //调用刚实例化出来的bean,注册bean定义
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        //清空调用后的BeanDefinitionRegistryPostProcessor
        currentRegistryProcessors.clear();
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
            //实例化实现了Ordered接口的BeanDefinitionRegistryPostProcessor
            if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        registryProcessors.addAll(currentRegistryProcessors);
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        currentRegistryProcessors.clear();
        //调用没有实现任何优先级接口的BeanDefinitionRegistryPostProcessor
        boolean reiterate = true;
        while (reiterate) {
            reiterate = false;
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                if (!processedBeans.contains(ppName)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                    reiterate = true;
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();
        }
        //调用 BeanDefinitionRegistryPostProcessor.postProcessBeanFactory方法
        invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
        //调用自己实现的BeanDefinitionRegistryPostProcessor.postProcessBeanFactory方法
        invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    }
    else {
        //没有实现BeanDefinitionRegistry接口的bean工厂,直接调用invokeBeanFactoryPostProcessors
        invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    }
    //调用所有的BeanDefinitionRegistryPostProcessor完毕
    //获取容器中所有的 BeanFactoryPostProcessor
    String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    //执行所有BeanFactoryPostProcessor.postProcessBeanFactory方法,按照order接口排序
    List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<String> orderedPostProcessorNames = new ArrayList<>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    for (String ppName : postProcessorNames) {
        if (processedBeans.contains(ppName)) {
        }
        else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
        }
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
        }
        else {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    for (String postProcessorName : orderedPostProcessorNames) {
        orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    for (String postProcessorName : nonOrderedPostProcessorNames) {
        nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
    //执行完成所有BeanFactoryPostProcessor.postProcessBeanFactory方法,清除所有缓存信息
    beanFactory.clearMetadataCache();
}
//我们接下来主要是看ConfigurationClassPostProcessor调用postProcessBeanDefinitionRegistry方法
private static void invokeBeanDefinitionRegistryPostProcessors(
        Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
    for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
        postProcessor.postProcessBeanDefinitionRegistry(registry);
    }
}
复制代码



接下来主要针对于,ConfigurationClassParser类进行解析操作处理

public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
    int registryId = System.identityHashCode(registry);
    if (this.registriesPostProcessed.contains(registryId)) {
        throw new IllegalStateException(
                "postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
    }
    if (this.factoriesPostProcessed.contains(registryId)) {
        throw new IllegalStateException(
                "postProcessBeanFactory already called on this post-processor against " + registry);
    }
    this.registriesPostProcessed.add(registryId);
    processConfigBeanDefinitions(registry);
}
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
    List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
    String[] candidateNames = registry.getBeanDefinitionNames();
    //循环最开始初始化的所有bean定义
    for (String beanName : candidateNames) {
        BeanDefinition beanDef = registry.getBeanDefinition(beanName);
        //对配置类(带有@Configuration标签)进行标记,后续实例化时有用
        if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
            if (logger.isDebugEnable()) {
                logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
            }
        }
        //进行标记,添加到配置类,候选集合中
        else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
            configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
        }
    }
    if (configCandidates.isEmpty()) {
        return;
    }
    //对所有配置类进行排序
    configCandidates.sort((bd1, bd2) -> {
        int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
        int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
        return Integer.compare(i1, i2);
    });
    // 创建我们通过@ComponentScan导入进来的bean name的生成器
    // 创建我们通过@Import导入进来的bean的名称
    SingletonBeanRegistry sbr = null;
    if (registry instanceof SingletonBeanRegistry) {
        sbr = (SingletonBeanRegistry) registry;
        if (!this.localBeanNameGeneratorSet) {
            BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
                    AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
            if (generator != null) {
                this.componentScanBeanNameGenerator = generator;
                this.importBeanNameGenerator = generator;
            }
        }
    }
    if (this.environment == null) {
        this.environment = new StandardEnvironment();
    }
    //创建一个类解析器
    ConfigurationClassParser parser = new ConfigurationClassParser(
            this.metadataReaderFactory, this.problemReporter, this.environment,
            this.resourceLoader, this.componentScanBeanNameGenerator, registry);
    Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
    Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
    do {
        /**解析配置类,包括@Component、@ComponentScans等需要扫描的类,都会被解析出来放入bean定义容器
         *@Configuration配置类为full配置类,其他的为lite配置类
         **/
        parser.parse(candidates);
        parser.validate();
        //获取到解析出来的配置类
        Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
        configClasses.removeAll(alreadyParsed);
        if (this.reader == null) {
            this.reader = new ConfigurationClassBeanDefinitionReader(
                    registry, this.sourceExtractor, this.resourceLoader, this.environment,
                    this.importBeanNameGenerator, parser.getImportRegistry());
        }
        //把所有@Import、@Bean解析出来的bean定义放入容器
        this.reader.loadBeanDefinitions(configClasses);
        alreadyParsed.addAll(configClasses);
        candidates.clear();
        if (registry.getBeanDefinitionCount() > candidateNames.length) {
            String[] newCandidateNames = registry.getBeanDefinitionNames();
            Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
            Set<String> alreadyParsedClasses = new HashSet<>();
            for (ConfigurationClass configurationClass : alreadyParsed) {
                alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
            }
            for (String candidateName : newCandidateNames) {
                if (!oldCandidateNames.contains(candidateName)) {
                    BeanDefinition bd = registry.getBeanDefinition(candidateName);
                    if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
                            !alreadyParsedClasses.contains(bd.getBeanClassName())) {
                        candidates.add(new BeanDefinitionHolder(bd, candidateName));
                    }
                }
            }
            candidateNames = newCandidateNames;
        }
    }
    while (!candidates.isEmpty());
    if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
        sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
    }
    if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
        ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
    }
}
//我们再来看看ConfigurationClassPostProcessor.invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    int factoryId = System.identityHashCode(beanFactory);
    if (this.factoriesPostProcessed.contains(factoryId)) {
        throw new IllegalStateException(
                "postProcessBeanFactory already called on this post-processor against " + beanFactory);
    }
    this.factoriesPostProcessed.add(factoryId);
    if (!this.registriesPostProcessed.contains(factoryId)) {
        processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
    }
    //这里会修改@Configuration配置类的bean定义,到时候实例化bean时,会使用CGLIB创建动态代理,@Bean中调用获取的bean都是容器中的bean,其他配置类的bean,获取的都是new出来的
    enhanceConfigurationClasses(beanFactory);
    beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}
复制代码



讲了bean定义的加载过程,现在我们来讲一下bean的实例化过程,bean的实例化,主要是finishBeanFactoryInitialization(beanFactory);这个方法

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    //bean工厂创建转化器
    if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
            beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
        beanFactory.setConversionService(
                beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
    }
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
    }
    //实例化AOP相关的组件
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        //调用工厂实例化方法,这个方法我们后面来分析
        getBean(weaverAwareName);
    }
    beanFactory.setTempClassLoader(null);
    //冻结所有bean定义,在实例化时,不允许再修改bean定义
    beanFactory.freezeConfiguration();
    //实例化所有bean
    beanFactory.preInstantiateSingletons();
}
复制代码

Spring IOC容器bean的实例化,到这基本就完成了,这次所有源代码的分析把重要的地方,大致流程都讲了一遍,但是有很多细节没有讲到,整体属于框架总体深入流程原理介绍。





相关文章
|
4月前
|
XML Java 测试技术
Spring IOC—基于注解配置和管理Bean 万字详解(通俗易懂)
Spring 第三节 IOC——基于注解配置和管理Bean 万字详解!
333 26
|
1月前
|
XML Java 数据格式
Spring IoC容器的设计与实现
Spring 是一个功能强大且模块化的 Java 开发框架,其核心架构围绕 IoC 容器、AOP、数据访问与集成、Web 层支持等展开。其中,`BeanFactory` 和 `ApplicationContext` 是 Spring 容器的核心组件,分别定位为基础容器和高级容器,前者提供轻量级的 Bean 管理,后者扩展了事件发布、国际化等功能。
|
3月前
|
Java 容器 Spring
什么是Spring IOC 和DI ?
IOC : 控制翻转 , 它把传统上由程序代码直接操控的对象的调用权交给容 器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转 移,从程序代码本身转移到了外部容器。 DI : 依赖注入,在我们创建对象的过程中,把对象依赖的属性注入到我们的类中。
|
6月前
|
XML Java 数据格式
【SpringFramework】Spring IoC-基于XML的实现
本文主要讲解SpringFramework中IoC和DI相关概念,及基于XML的实现方式。
156 69
|
6月前
|
Java Spring 容器
【SpringFramework】Spring IoC-基于注解的实现
本文主要记录基于Spring注解实现IoC容器和DI相关知识。
103 21
|
Java Spring
Spring原理学习系列之一:注解原理解析
对于Spring注解大家肯定都不陌生,在日常开发工作中也会经常使用到注解。有时候提问小伙伴,注解的原理是什么,大部分都回答是利用了反射机制。但是继续深入提问,在Spring中是如何解析这些自带注解以及注解到底在什么时候起作用等问题时,很多人都会犯嘀咕。同样我在实际使用的过程中,也会有相同的困惑。所以一直想探究下注解实际的工作原理以及设计思想。用此文记录下自己对于注解原理的理解,也为有同样疑问的小伙伴提供些不同的理解角度。 原理解析 使用实例
Spring原理学习系列之一:注解原理解析
|
3月前
|
前端开发 Java 数据库
微服务——SpringBoot使用归纳——Spring Boot集成Thymeleaf模板引擎——Thymeleaf 介绍
本课介绍Spring Boot集成Thymeleaf模板引擎。Thymeleaf是一款现代服务器端Java模板引擎,支持Web和独立环境,可实现自然模板开发,便于团队协作。与传统JSP不同,Thymeleaf模板可以直接在浏览器中打开,方便前端人员查看静态原型。通过在HTML标签中添加扩展属性(如`th:text`),Thymeleaf能够在服务运行时动态替换内容,展示数据库中的数据,同时兼容静态页面展示,为开发带来灵活性和便利性。
98 0
|
3月前
|
XML Java 数据库连接
微服务——SpringBoot使用归纳——Spring Boot集成MyBatis——基于 xml 的整合
本教程介绍了基于XML的MyBatis整合方式。首先在`application.yml`中配置XML路径,如`classpath:mapper/*.xml`,然后创建`UserMapper.xml`文件定义SQL映射,包括`resultMap`和查询语句。通过设置`namespace`关联Mapper接口,实现如`getUserByName`的方法。Controller层调用Service完成测试,访问`/getUserByName/{name}`即可返回用户信息。为简化Mapper扫描,推荐在Spring Boot启动类用`@MapperScan`注解指定包路径避免逐个添加`@Mapper`
109 0
|
3月前
|
Java 测试技术 微服务
微服务——SpringBoot使用归纳——Spring Boot中的项目属性配置——少量配置信息的情形
本课主要讲解Spring Boot项目中的属性配置方法。在实际开发中,测试与生产环境的配置往往不同,因此不应将配置信息硬编码在代码中,而应使用配置文件管理,如`application.yml`。例如,在微服务架构下,可通过配置文件设置调用其他服务的地址(如订单服务端口8002),并利用`@Value`注解在代码中读取这些配置值。这种方式使项目更灵活,便于后续修改和维护。
47 0
|
3月前
|
SQL Java 数据库连接
微服务——SpringBoot使用归纳——Spring Boot使用slf4j进行日志记录—— application.yml 中对日志的配置
在 Spring Boot 项目中,`application.yml` 文件用于配置日志。通过 `logging.config` 指定日志配置文件(如 `logback.xml`),实现日志详细设置。`logging.level` 可定义包的日志输出级别,例如将 `com.itcodai.course03.dao` 包设为 `trace` 级别,便于开发时查看 SQL 操作。日志级别从高到低为 ERROR、WARN、INFO、DEBUG,生产环境建议调整为较高级别以减少日志量。本课程采用 yml 格式,因其层次清晰,但需注意格式要求。
216 0
下一篇
oss创建bucket