写点什么

🏆「推荐收藏」【Spring 源码专题】彻底让你明白【IOC 容器初始化】运行原理和源码流程

发布于: 22 分钟前
🏆「推荐收藏」【Spring源码专题】彻底让你明白【IOC容器初始化】运行原理和源码流程

前言介绍

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


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

  • 一定要学会抓重点,归纳核心类、核心方法、核心步骤;

  • 分析源码我们不需要太过于纠结细节,不然,这个源码最起码得分析月才能分析完

  • 主要的目的是分析整个容器初始化过程,怎么初始化 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。

  • 最后实际进行初始化然后保存到容器中。




来实现各种不同的功能;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进行注册相关的beanpublic 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 定义,我们不分析这种方式

  3. 这步比较关键,这步完成后,配置文件/配置类就会解析成一个 Bean 定义,注册到 BeanFactory 中,

  4. 这里说的 Bean 还没有初始化,只是配置信息都提取出来了,

  5. 注册也只是将这些信息都保存到了注册中心(说到底核心是一个 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 容器,加载并注册 BeanIoC 初始化里面最重要的部分。


关键是以下几步:


  • 初始化 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 规则进行解析

  3. Spring 的 Bean 规则进行解析这个过程是 BeanDefinitionDocumentReader 来实现的,里面包含了各种 Spring Bean 定义规则的处理。

  4. 这里我觉得核心知识点就是 Spring Bean 规则的解析,简单点来说,里面包含了我们在 XML 配置的那些信息,怎么解析成容器中 BeanDefinition 的规则和步骤。这部分由于和主要流程关系不大。

  5. 在这因为 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 的实例化,到这基本就完成了,这次所有源代码的分析把重要的地方,大致流程都讲了一遍,但是有很多细节没有讲到,整体属于框架总体深入流程原理介绍。

发布于: 22 分钟前阅读数: 2
用户头像

我们始于迷惘,终于更高水平的迷惘。 2020.03.25 加入

🏆 【酷爱计算机技术、醉心开发编程、喜爱健身运动、热衷悬疑推理的”极客狂人“】 🏅 【Java技术领域,MySQL技术领域,APM全链路追踪技术及微服务、分布式方向的技术体系等】 🤝未来我们希望可以共同进步🤝

评论

发布
暂无评论
🏆「推荐收藏」【Spring源码专题】彻底让你明白【IOC容器初始化】运行原理和源码流程