spring Bean加载过程

作者: 爱撒谎的男孩 | 来源:发表于2018-10-07 22:29 被阅读72次

    spring Bean加载过程

    1、找准入口 ,使用ClassPathXmlApplicationContext加载配置文件,用于加载classPath下的配置文件

    //第一行,执行完成之后就完成了spring配置文件的加载,刷新spring上下文
    ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext(
                    "classpath:spring-mvc.xml");
    //获取实例Bean
    Person person=context.getBean("person",Person.class);
    

    ClassPathXmlApplicationContext的继承关系如下:

    https://images2015.cnblogs.com/blog/801753/201702/801753-20170201125310058-568989522.png

    2、现在开始仔细分析第一句,可以看出第一句就已经完成了spring配置文件的加载

    ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext(
                    "classpath:spring-mvc.xml");
    

    3、查看classPathXmlApplicationContext的源码,下面表格是对象

    对象名 类 型 作 用 归属类
    configResources Resource[] 配置文件资源对象数组 ClassPathXmlApplicationContext
    configLocations String[] 配置文件字符串数组,存储配置文件路径 AbstractRefreshableConfigApplicationContext
    beanFactory DefaultListableBeanFactory 上下文使用的Bean工厂 AbstractRefreshableApplicationContext
    beanFactoryMonitor Object Bean工厂使用的同步监视器 AbstractRefreshableApplicationContext
    id String 上下文使用的唯一Id,标识此ApplicationContext AbstractApplicationContext
    parent ApplicationContext 父级ApplicationContext AbstractApplicationContext
    beanFactoryPostProcessors List<BeanFactoryPostProcessor> 存储BeanFactoryPostProcessor接口,Spring提供的一个扩展点 AbstractApplicationContext
    startupShutdownMonitor Object refresh方法和destory方法公用的一个监视器,避免两个方法同时执行 AbstractApplicationContext
    shutdownHook Thread Spring提供的一个钩子,JVM停止执行时会运行Thread里面的方法 AbstractApplicationContext
    resourcePatternResolver ResourcePatternResolver 上下文使用的资源格式解析器 AbstractApplicationContext
    lifecycleProcessor LifecycleProcessor 用于管理Bean生命周期的生命周期处理器接口 AbstractApplicationContext
    messageSource MessageSource 用于实现国际化的一个接口 AbstractApplicationContext
    applicationEventMulticaster ApplicationEventMulticaster Spring提供的事件管理机制中的事件多播器接口 AbstractApplicationContext
    applicationListeners Set<ApplicationListener> Spring提供的事件管理机制中的应用监听器 AbstractApplicationContext

    4、从构造方法可以看出,加载spring配置文件实际调用的是如下构造方法:

    public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
                throws BeansException {
            //设置父级的ApplicationContext,null
            super(parent);
            //1.设置配置文件的路径, 2. 将路径中的占位符${placeholder}使用系统的变量替换
            setConfigLocations(configLocations);
            if (refresh) {
                refresh();
            }
        }
    

    5、进入setConfigLocations(configLocations);的源码,这个方法是父类AbstractRefreshableConfigApplicationContext中的方法

    1. 设置配置文件的路径
    2. 替换路径中的占位符`${placeholder}`为系统变量中的值
    
    //locations : 配置文件路径-+
    public void setConfigLocations(String[] locations) {
            if (locations != null) {
                //断言
                Assert.noNullElements(locations, "Config locations must not be null");
                //存储配置文件路径的数组,存储去掉占位符后的文件路径数组
                this.configLocations = new String[locations.length];
                //遍历locations,解析占位符
                for (int i = 0; i < locations.length; i++) {
                        //调用resolvePath解析占位符
                    this.configLocations[i] = resolvePath(locations[i]).trim();
                }
            }
            else {
                this.configLocations = null;
            }
        }
    

    6、进入resolvePath的源码可以知道,实际上执行的是AbstractPropertyResolverdoResolvePlaceholders方法,如下

    /**
    * text : 需要解析的路径
    * PropertyPlaceholderHelper : 这个是解析系统占位符的辅助类,主要用来将占位符替换成系统的环境变量
    */
    private String doResolvePlaceholders(String text, PropertyPlaceholderHelper helper) {
            //调用PropertyPlaceholderHelper类中的replacePlaceholders方法
            return helper.replacePlaceholders(text, new PropertyPlaceholderHelper.PlaceholderResolver() {
                public String resolvePlaceholder(String placeholderName) {
                    return getPropertyAsRawString(placeholderName);
                }
            });
        }
    

    7、进入PropertyHelper中的replacePlaceholders方法,实际上调用org.springframework.util.PropertyPlaceholderHelper这个类的parseStringValue解析占位符

    1. 实际调用的是parseStringValue方法
    2. this.placeholderPrefix这个是占位符的前缀 {,在创建PropertyHelper的时候就已经指定了占位符的placeholderPrefix="{" ,placeholderSuffix="}",valueSeparator=":"
    3. 使用parseStringValue方法递归解析占位符中的内容
    4. parseStringValue方法中使用两次递归
      1. placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders);,这个是第一次,用来解析占位符中的placeholder是否还包含占位符,如果有占位符需要将其抽离出来,去掉${}
      2. propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders); ,这个是第二次递归调用,用来解析propVal中的占位符
    public String replacePlaceholders(String value, PlaceholderResolver placeholderResolver) {
            Assert.notNull(value, "Argument 'value' must not be null.");
            //调用的是parseStringValue方法
            return parseStringValue(value, placeholderResolver, new HashSet<String>());
        }
    
    /**
    * strVal  : 需要解析的字符串,就是配置文件的路径
    * placeholderResolver : 策略接口,占位符解析器
    * visitedPlaceholders : 存储已经访问过的占位符
    **/
    protected String parseStringValue(
                String strVal, PlaceholderResolver placeholderResolver, Set<String> visitedPlaceholders) {
            //将strval转换成StringBuilder,便于后续到操作
            StringBuilder buf = new StringBuilder(strVal);
        
        //this.placeholderPrefix这个是占位符的前缀 ${,在创建PropertyHelper的时候就已经指定了占位符的placeholderPrefix="${" ,placeholderSuffix="}",valueSeparator=":"
        //获取前缀在这个配置文件路径中的开始索引    
            int startIndex = strVal.indexOf(this.placeholderPrefix);
        
            while (startIndex != -1) {
                //占位符前缀在路径中的结束索引
                int endIndex = findPlaceholderEndIndex(buf, startIndex);
                
                //如果结束索引存在
                if (endIndex != -1) {
                    
                    //此时取出${plcaeholder}中的占位符内容placeholder
                    String placeholder = buf.substring(startIndex + this.placeholderPrefix.length(), endIndex);
                    
                    //保存取出来的占位符内容placeholder
                    String originalPlaceholder = placeholder;
                    
                    //如果占位符中的内容已经被访问过了,抛出出异常返回,递归结束的条件
                    if (!visitedPlaceholders.add(originalPlaceholder)) {
                        throw new IllegalArgumentException(
                                "Circular placeholder reference '" + originalPlaceholder + "' in property definitions");
                    }
                    
                    //递归解析已经取出的占位符中的内容 palceholder
                    placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders);
                    
                    
                    //这个最重要的一步,将解析占位符内容placeholder的值,比如将java.version转换成1.8.0_60
                    String propVal = placeholderResolver.resolvePlaceholder(placeholder);
                    
                    if (propVal == null && this.valueSeparator != null) {
                        int separatorIndex = placeholder.indexOf(this.valueSeparator);
                        if (separatorIndex != -1) {
                            String actualPlaceholder = placeholder.substring(0, separatorIndex);
                            String defaultValue = placeholder.substring(separatorIndex + this.valueSeparator.length());
                            propVal = placeholderResolver.resolvePlaceholder(actualPlaceholder);
                            if (propVal == null) {
                                propVal = defaultValue;
                            }
                        }
                    }
                    //如果解析出来的占位符不为空,比如${java.version}将被解析成 1.8.0_60
                    if (propVal != null) {
                        //此时继续递归解析出1.8.0_60中的占位符
                        propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders);
                        //将路径中的占位符替换成系统变量的值,比如将${java.version} 替换成 1.8.0_60
                        buf.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal);
                        if (logger.isTraceEnabled()) {
                            logger.trace("Resolved placeholder '" + placeholder + "'");
                        }
                        //继续在路径字符串中剩余的子串中查找占位符,如果有占位符,那么还会继续解析占位符
                        startIndex = buf.indexOf(this.placeholderPrefix, startIndex + propVal.length());
                    }
                    else if (this.ignoreUnresolvablePlaceholders) {
                        // Proceed with unprocessed value.
                        startIndex = buf.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length());
                    }
                    else {
                        throw new IllegalArgumentException("Could not resolve placeholder '" +
                                placeholder + "'" + " in string value \"" + strVal + "\"");
                    }
                    //将已转换成功的占位符从以访问的集合中移除即可
                    visitedPlaceholders.remove(originalPlaceholder);
                }
                else {
                    startIndex = -1;
                }
            }
    
            return buf.toString();   //将解析完成之后的配置文件返回
        }
    
    

    8、总之一句话 : setConfigLocations(configLocations);的作用就是将客户端传入的配置文件路径,先解析占位符,之后将解析完成之后的配置文件路径存储起来

    9、现在进入ClassPathXmlApplicationContext中的refresh方法,实际上调用的是父类org.springframework.context.support.AbstractApplicationContext的方法,下面我们一个一个方法分析

    //刷新spring上下文
    public void refresh() throws BeansException, IllegalStateException {
            synchronized (this.startupShutdownMonitor) {
                //在刷新之前设置一些参数,比如设置开始时间戳,上下文是否激活的标志,输出刷新上下文的信息,验证一些必要的属性
                prepareRefresh();
    
                //需要创建beanFactory,如果已经存在beanFactory,那么关闭,详细其请看 10
                ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
                // 准备上下文工厂,详情见12
                prepareBeanFactory(beanFactory);
    
                try {
                    //允许子类向后置处理器添加组件
                    postProcessBeanFactory(beanFactory);
    
                    // 调用BeanFactoryPostProcessor和BeanDefintionRegistoryPostProcessor这两个后置处理器
                    invokeBeanFactoryPostProcessors(beanFactory);
    
                    // 注册BeanPostProcessor,用来拦截bean的创建,详情见 14
                    registerBeanPostProcessors(beanFactory);
    
                    //初始化消息源
                    initMessageSource();
    
                    // 初始化应用程序事件广播器,用户可以自定义一个事件广播器,如果用户没有定义,那么使用默认的事件广播器SimpleApplicationEventMulticaster
                    initApplicationEventMulticaster();
    
                    // 在其他子类中初始化bean
                    onRefresh();
    
                    // 检测事件监听器
                    registerListeners();
    
                    //完成实例化剩余的单例(non-lazy-init)
                    finishBeanFactoryInitialization(beanFactory);
    
                    // 完成刷新,初始化生命周期处理器......
                    finishRefresh();
                }
    
                catch (BeansException ex) {
                    // Destroy already created singletons to avoid dangling resources.
                    destroyBeans();
    
                    // Reset 'active' flag.
                    cancelRefresh(ex);
    
                    // Propagate exception to caller.
                    throw ex;
                }
            }
        }
    

    10、进入obtainFreshBeanFactory ,分析源码

    //AbastractApplicationContext的方法
    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
            //实际刷新上下文的方法,这个方法就是实际的刷新上下文方法,其中会调用loadBeanDefinitions(beanFactory);加载配置文件中的内容到BeanDefiniton中
            refreshBeanFactory();
            ConfigurableListableBeanFactory beanFactory = getBeanFactory();
            if (logger.isDebugEnabled()) {
                logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
            }
            return beanFactory;
        }
    
    
        //org.springframework.context.support.AbstractRefreshableApplicationContext中的方法
        //AbstractApplicationContext的子类中的方法
        @Override
        protected final void refreshBeanFactory() throws BeansException {
            //如果其中有beanfactory,那么销毁
            if (hasBeanFactory()) {
                destroyBeans();
                closeBeanFactory();
            }
            
            try {
                //重新创建一个beanFactory
                DefaultListableBeanFactory beanFactory = createBeanFactory();
                //设置序列化id
                beanFactory.setSerializationId(getId());
                
                //定制beanFactory,设置相关属性,包括是否允许覆盖名称的不同定义的对象及循环依赖以及
                //设置@Autowired和@Qualifier,注解解析器QualifierAnnotationAutowireCandidateResolver
                customizeBeanFactory(beanFactory);
                //加载BeanDefine 详情见  11
                loadBeanDefinitions(beanFactory);
                synchronized (this.beanFactoryMonitor) {
                    this.beanFactory = beanFactory;
                }
            }
            catch (IOException ex) {
                throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
            }
        }
    
    

    11、 进入loadBeanDefinitions(beanFactory);方法

    ​ 1、主要调用的是XmlBeanDefinitionReader其中的loadBeanDefinitions方法,详情请看我的spring之BeanDefinitonReader解析

        //这个是org.springframework.context.support.AbstractXmlApplicationContext类中的方法
        protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
            
            //创建要给beanDefinitionReader,用于读取BeanDefinition
            //详情见 BeanDefinitonReader的源码解析
            XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
    
            //配置XmlBeanDefinitionReader
            beanDefinitionReader.setEnvironment(this.getEnvironment());
            beanDefinitionReader.setResourceLoader(this);   
            beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
        
            initBeanDefinitionReader(beanDefinitionReader);
            //加载BeanDefiniton,主要的功能从配置文件中读取BeanDefiniton注册到注册表中
            loadBeanDefinitions(beanDefinitionReader);
        }
    

    12、prepareBeanFactory :准备BeanFactory,目前还不太明白,后续分析

    //准备BeanFactory,设置一些参数,比如后置处理器,
    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
            //设置类加载器
            beanFactory.setBeanClassLoader(getClassLoader());
            
        //设置表达式解析器,用来解析BeanDefiniton中的带有表达式的值
            beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
            
        
            beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    
            // 配置后置处理器,主要的作用就是在spring实例化bean的前后做一些操作
            beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
            
            //忽略自动装配的类,这些类都不能使用@Resource或者@Autowired自动装配获取对象
            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.registerResolvableDependency(BeanFactory.class, beanFactory);
            beanFactory.registerResolvableDependency(ResourceLoader.class, this);
            beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
            beanFactory.registerResolvableDependency(ApplicationContext.class, this);
    
            //在添加一个应用程序监听器
            beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
    
            //检查这些类是否被
            if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
                beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
    
                beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
            }
    
            // 将下面这些类注册到容器中,使用registerSingleton方法注册,我们可以直接从容器中获取这些类的对象使用
            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());
            }
        }
    

    13、调用BeanFactory的后置处理器,主要的功能就是调用注册在容器中的BeanFactoryPostProcessor和BeanDefinitionRegistoryPostProcessor

    ​ 1、BeanFactoryPostProcessor这个是后置处理器,实现这个类可以修改容器中bean的数据信息,可以在spring配置文件加载之后执行,在单例实例化之前调用,因此可以在其中修改和获取bean的实例化的信息,通过BeanDefintion

    ​ 2、先调用BeanDefinitionRegistryPostProcessor,按照优先级调用,比如分为实现PriorityOrdered这个接口和Orderd这个接口的,分开调用

    ​ 3、再调用实现BeanFactoryPostProcessor这个接口的,也是按照优先级别调用,和上面的流程一样

    //实例化和调用BeanFactory后置处理器,必须在单例实例化之前调用
    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
            //调用后置处理器注册委托类的方法调用,getBeanFactoryPostProcessors用于获取注册的全部的BeanFactoryPostProcessor
            PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
        }
    
    //实际的调用方法,PostProcessorRegistrationDelegate中的方法
    public static void invokeBeanFactoryPostProcessors(
                ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    
            // Invoke BeanDefinitionRegistryPostProcessors first, if any.
            Set<String> processedBeans = new HashSet<String>();
            
            //如果beanFactory是BeanDefinitionRegistry的子类,BeanDefinitionRegistry使用来向注册表中注册Bean的元信息的(BeanDefintion)
            if (beanFactory instanceof BeanDefinitionRegistry) {
                BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
                
                //存放BeanFactoryPostProcessor
                List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
                
                //存放BeanDefinitionRegistryPostProcessor
                List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
                        new LinkedList<BeanDefinitionRegistryPostProcessor>();
                
                //遍历。判断是否是BeanDefinitionRegistryPostProcessor实例
                for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                    if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                        BeanDefinitionRegistryPostProcessor registryPostProcessor =
                                (BeanDefinitionRegistryPostProcessor) postProcessor;
                        
                            //调用BeanDefinitionRegistryPostProcessor
                        registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
                        //添加
                        registryPostProcessors.add(registryPostProcessor);
                    }
                    else {
                        //表示这个是BeanFactoryPostProcessor实例,添加进集合
                        regularPostProcessors.add(postProcessor);
                    }
                }
    
                //--- 根据类型类型获取beanFactory中注册的BeanDefinitionRegistryPostProcessor的bean的所有名称数组
                String[] postProcessorNames =
                        beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    
                // ---- 首先调用的是BeanDefinitionRegistryPostProcessor类型的后置处理器
                
                //存放实现PriorityOrdered这个接口的BeanDefinitionRegistryPostProcessor
                List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
                
                //遍历,如果实现了PriorityOrdered这个接口就保存下来
                for (String ppName : postProcessorNames) {
                    if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                        priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                    }
                }
                
                //按照优先级排序
                OrderComparator.sort(priorityOrderedPostProcessors);
                //添加进入集合
                registryPostProcessors.addAll(priorityOrderedPostProcessors);
                
                //首先调用实现PriorityOrdered这个接口的BeanDefinitionRegistryPostProcessor
                invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);
    
                // ---- 下面是调用实现Orderd这个接口的BeanDefinitionRegistryPostProcessor
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
                for (String ppName : postProcessorNames) {
                    if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                        orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                    }
                }
                OrderComparator.sort(orderedPostProcessors);
                registryPostProcessors.addAll(orderedPostProcessors);
                invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);
    
                
                // ---- 最终调用剩余全部的BeanDefinitionRegistryPostProcessor
                
                boolean reiterate = true;
                while (reiterate) {
                    reiterate = false;
                    postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                    for (String ppName : postProcessorNames) {
                        if (!processedBeans.contains(ppName)) {
                            BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
                            registryPostProcessors.add(pp);
                            processedBeans.add(ppName);
                            pp.postProcessBeanDefinitionRegistry(registry);
                            reiterate = true;
                        }
                    }
                }
    
                // 调用BeanFactoryPostProcessor接口中的方法,因为BeanDefitionRegistory继承了这个接口
                invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
                invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
            }
    
            else {
                // Invoke factory processors registered with the context instance.
                invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
            }
    
            //--- 下面是调用实现BeanFactoryPostProcessor接口的类,和上面的流程一样
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    
            // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
            // Ordered, and the rest.
            List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
            List<String> orderedPostProcessorNames = new ArrayList<String>();
            List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
            for (String ppName : postProcessorNames) {
                if (processedBeans.contains(ppName)) {
                    // skip - already processed in first phase above
                }
                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);
                }
            }
    
            // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
            OrderComparator.sort(priorityOrderedPostProcessors);
            invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    
            // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
            List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
            for (String postProcessorName : orderedPostProcessorNames) {
                orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
            }
            OrderComparator.sort(orderedPostProcessors);
            invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
    
            // Finally, invoke all other BeanFactoryPostProcessors.
            List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
            for (String postProcessorName : nonOrderedPostProcessorNames) {
                nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
            }
            invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
        }
    
    

    14、注册BeanPostProcessor,用来拦截Bean的创建,这个接口可以实现在Bean初始化和初始化之后执行相关的操作,会有单独一篇解读

    ​ 1、这个注册BeanPostProcessor思想和上面的调用BeanFactoryPostProcessor的思想一样,按照优先级注册,通过判断是否实现PriorityOrdered和orderd接口,按照优先级排序注册到BeanFactory中,其实注册的方法就是将这个后置处理器添加到beanFactory中的List<BeanPostProcessor> beanPostProcessors = new ArrayList<BeanPostProcessor>()

    //依然这里依然调用的PostProcessorRegistrationDelegate,其中包含了注册后置处理器和调用后置处理器的方法,相当于一个代理人
    protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
            PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
        }
    
    //PostProcessorRegistrationDelegate中的注册BeanPostProcessors的方法
    //其中beanFactory这个新创建的beanFactory,其中的BeanPostProcessor都没有注册,applicationContext这个是之前创建的,其中的处理器已经注册过了
    public static void registerBeanPostProcessors(
                ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
            
            //根据类型新加载全部的BeanFactoryProcessor的类,
            String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
    
            //创建BeanPostProcessor检测器
            int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
            beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
    
            // Separate between BeanPostProcessors that implement PriorityOrdered,
            // Ordered, and the rest.
            List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
            List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
            List<String> orderedPostProcessorNames = new ArrayList<String>();
            List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
            for (String ppName : postProcessorNames) {
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
                    priorityOrderedPostProcessors.add(pp);
                    if (pp instanceof MergedBeanDefinitionPostProcessor) {
                        internalPostProcessors.add(pp);
                    }
                }
                else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    orderedPostProcessorNames.add(ppName);
                }
                else {
                    nonOrderedPostProcessorNames.add(ppName);
                }
            }
    
            // First, register the BeanPostProcessors that implement PriorityOrdered.
            OrderComparator.sort(priorityOrderedPostProcessors);
            registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
    
            // Next, register the BeanPostProcessors that implement Ordered.
            List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
            for (String ppName : orderedPostProcessorNames) {
                BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
                orderedPostProcessors.add(pp);
                if (pp instanceof MergedBeanDefinitionPostProcessor) {
                    internalPostProcessors.add(pp);
                }
            }
            OrderComparator.sort(orderedPostProcessors);
            registerBeanPostProcessors(beanFactory, orderedPostProcessors);
    
            // Now, register all regular BeanPostProcessors.
            List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
            for (String ppName : nonOrderedPostProcessorNames) {
                BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
                nonOrderedPostProcessors.add(pp);
                if (pp instanceof MergedBeanDefinitionPostProcessor) {
                    internalPostProcessors.add(pp);
                }
            }
            registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
    
            // Finally, re-register all internal BeanPostProcessors.
            OrderComparator.sort(internalPostProcessors);
            registerBeanPostProcessors(beanFactory, internalPostProcessors);
    
            beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
        }
    

    总结

    1、入口

    ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("spring-test.xml");
    

    2、解析传入的路径中的占位符,集合org.springframework.core.env.AbstractPropertyResolverorg.springframework.util.PropertyPlaceholderHelper

    3、刷新上下文

    ​ 1、prepareRefresh() : 准备刷新,设置一些活动标志,比如开始时间,当前的状态

    ​ 2、ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory():从spring的配置文件中加载bean,封装成BeanDefinition,注册到注册表中,创建beanFactory

    ​ 3、prepareBeanFactory(beanFactory); :准备BeanFactory,设置累加载器,添加后置处理器,SPL表达式解析器,向ioc容器中注入一些组件

    ​ 4、postProcessBeanFactory(beanFactory); : 允许子类做一些处理操作

    ​ 5、invokeBeanFactoryPostProcessors(beanFactory); :调用BeanFactoryProcessor,先是调用BeanDefitionRegistoyPostProcessor,之后调用BeanFactoryProcessor

    ​ 6、registerBeanPostProcessors(beanFactory); : 将配置文件中读取的Bean的后置处理器注册到容器中

    ​ 7、initMessageSource(); :初始化消息源,用于国际化

    ​ 8、initApplicationEventMulticaster() : 初始化事件广播器,判断容器中是否已经注册了该组件,如果没有该组件,那么使用默认的

    ​ 9、onRefresh(); :子类初始化一些特殊的bean

    ​ 10、registerListeners(); :注册事件监听器

    ​ 11、finishBeanFactoryInitialization(beanFactory) :完成初始化,初始化非懒加载的bean

    ​ 12、finishRefresh(); :完成刷新,最后一步,初始化生命周期处理器,派发事件

    参考文章

    相关文章

      网友评论

        本文标题:spring Bean加载过程

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