• 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();
                }
            }
        }
    }
    

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

  • 相关阅读:
    VFP获取 SQL Server 的数据表、触发器、存储过程、视图等脚本
    VFP控制Excel操作集
    MS SqlServer 的日期格式化函数 Convert
    VFP 图形文件与剪切板互换的API解决方法
    VFP中OCX控件注册检测及自动注册
    VFP检测SQL Server的五个实例代码
    缓存方案笔记
    windows访问控制列表 --ACL(Access Control List)
    cnblog排版
    GIT常用命令
  • 原文地址:https://www.cnblogs.com/binarylei/p/10423707.html
Copyright © 2020-2023  润新知