zoukankan      html  css  js  c++  java
  • ApplicationContext(九)初始化非延迟的 bean

    ApplicationContext(九)初始化非延迟的 bean

    此至,ApplicationContext 已经完成了全部的准备工作,开始初始化剩余的 bean 了(第 11 步)。

    public void refresh() throws BeansException, IllegalStateException {
        // 11. 初始化剩余的 bean (部分在 invokeBeanFactoryPostProcessors 已经初始化)
        finishBeanFactoryInitialization(beanFactory);
    }
    

    finishBeanFactoryInitialization 主要是实例化非懒加载的 bean。

    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // 1. 注册 ConversionService,注意 beanName 必须为 conversionService
        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));
        }
    
        // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        for (String weaverAwareName : weaverAwareNames) {
            getBean(weaverAwareName);
        }
    
        // Stop using the temporary ClassLoader for type matching.
        beanFactory.setTempClassLoader(null);
    
        // 2. 冻结所有的 bean 定义,说明注册的 bean 定义将不被修改
        beanFactory.freezeConfiguration();
    
        // 3. 初始化剩下的 bean
        beanFactory.preInstantiateSingletons();
    }
    

    一、注册 ConversionService

    (1) String2DateConverter

    public class String2DateConverter implements Converter<String, Date> {
        @Override
        public Date convert(String source) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            try {
                return sdf.parse(source);
            } catch (ParseException e) {
                ;
            }
            return null;
        }
    }
    

    (2) 注册

    注意:beanName 必须为 conversionService

    <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="com.github.binarylei.spring01.day0728.conversionservice.String2DateConverter"/>
            </set>
        </property>
    </bean>
    

    (3) 测试

    @Test
    public void test() {
        DefaultConversionService service = new DefaultConversionService();
        service.addConverter(new String2DateConverter());
    
        Date value = service.convert("2018-08-02", Date.class);
        System.out.println(value);
    }
    

    二、冻结配置

    源代码【DefaultListableBeanFactory】

    public void freezeConfiguration() {
        this.configurationFrozen = true;
        this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
    }
    

    三、初始化非延迟加载

    public void preInstantiateSingletons() throws BeansException {
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Pre-instantiating singletons in " + this);
        }
    
        // 1. 创建剩下的单实例 bean
        List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
    
        // Trigger initialization of all non-lazy singleton beans...
        for (String beanName : beanNames) {
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                if (isFactoryBean(beanName)) {
                    final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
                            @Override
                            public Boolean run() {
                                return ((SmartFactoryBean<?>) factory).isEagerInit();
                            }
                        }, getAccessControlContext());
                    }
                    else {
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                ((SmartFactoryBean<?>) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        getBean(beanName);
                    }
                }
                else {
                    getBean(beanName);
                }
            }
        }
    
        // 2. 筛选出实现了 SmartInitializingSingleton 接口的 bean,回调 afterSingletonsInstantiated() 方法
        //    @EventListener 注解的方式注册监听器就是在这一步完成的
        for (String beanName : beanNames) {
            Object singletonInstance = getSingleton(beanName);
            if (singletonInstance instanceof SmartInitializingSingleton) {
                final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
                if (System.getSecurityManager() != null) {
                    AccessController.doPrivileged(new PrivilegedAction<Object>() {
                        @Override
                        public Object run() {
                            smartSingleton.afterSingletonsInstantiated();
                            return null;
                        }
                    }, getAccessControlContext());
                }
                else {
                    smartSingleton.afterSingletonsInstantiated();
                }
            }
        }
    }
    

    每天用心记录一点点。内容也许不重要,但习惯很重要!

  • 相关阅读:
    《Android 4游戏高级编程(第2版)》书评
    push研究——Apache Mina探索初步
    Android UI开发第二十三篇——分享书架UI实现
    cookie学习总结
    Web.xml配置详解
    Java序列化的机制和原理
    Java高级技术(汇总中...)
    [Java]HashMap的两种排序方式
    jdk与jre的区别
    DM,NLP常用算法汇总
  • 原文地址:https://www.cnblogs.com/binarylei/p/10423707.html
Copyright © 2011-2022 走看看