初始化非延迟加载单例和finishRefresh

初始化非延迟加载单例

完成BeanFactory的初始化工作,其中包括ConversionService的设置、配置冻结以及非延迟加载的bean的初始化工作。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // 为上下文初始化转换
        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));
        }

        // 尽早初始化LoadTimeWeaverAware bean,以便尽早注册它们的转换器。
        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        for (String weaverAwareName : weaverAwareNames) {
            getBean(weaverAwareName);
        }

        // 停止使用临时类装入器进行类型匹配。
        beanFactory.setTempClassLoader(null);

        // 允许缓存所有bean定义元数据,冻结所有的bean定义,不再被修改
        beanFactory.freezeConfiguration();

        // 实例化所有剩余的(非延迟初始化)单例。
        beanFactory.preInstantiateSingletons();
    }

首先我们来了解一下ConversionService类提供的作用。

1.ConversionService的设置

之前我们提到过使用自定义类型转换器从String转换为Date的方式,那么,在Spring中还提供了另一种转换方式:使用Converter。我们同样用一个简单的示例来了解Converter的使用方式。

定义转换器:

public class MyConverter implements Converter<String, Date> {
    @Override
    public Date convert(String source) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            Date date = sdf.parse(source);
            return  date;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
    //测试
    public static void main(String[] args){
        DefaultConversionService conversionService = new DefaultConversionService();
        conversionService.addConverter(new MyConverter());
        String date = "2019-01-04 12:23:34";
        System.out.println(conversionService.convert(date,Date.class));
    }
}

配置文件:

<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
       <property name="converters">
           <list>
               <bean class="com.joe.mytag.application.MyConverter"/>
           </list>
       </property>
   </bean>

运行上述测试代码:

Fri Jan 04 12:23:34 CST 2019

通过以上功能我们看到了Converter以及ConversionService提供的便利服务,其中的配置就是在当前函数中被初始化的。

2.冻结配置

冻结所有的bean定义,说明注册的bean定义将不被修改或进行任何一步的处理。

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

3.初始化非延迟加载

ApplicationContext实现的默认行为就是在启动时将所有单例bean提前进行实例化。提前实例化意味着作为初始化的一部分,ApplicationContext实例会创建并配置所有的单例bean。通常情况下这是一种好事,因为这样在配置中的任何错误就会立即被发现(否则的话可能要花费几个小时或者几天)。而这个实例化的过程就是在preInstantiateSingletons中完成的。

public void preInstantiateSingletons() throws BeansException {
        if (logger.isTraceEnabled()) {
            logger.trace("Pre-instantiating singletons in " + this);
        }

        // 遍历副本以允许init方法注册新的bean定义。
        List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

        // 触发所有非延迟单例bean的初始化…
        for (String beanName : beanNames) {
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                if (isFactoryBean(beanName)) {
                    Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                    if (bean instanceof FactoryBean) {
                        final FactoryBean<?> factory = (FactoryBean<?>) bean;
                        boolean isEagerInit;
                        if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                            isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                                            ((SmartFactoryBean<?>) factory)::isEagerInit,
                                    getAccessControlContext());
                        }
                        else {
                            isEagerInit = (factory instanceof SmartFactoryBean &&
                                    ((SmartFactoryBean<?>) factory).isEagerInit());
                        }
                        if (isEagerInit) {
                            getBean(beanName);
                        }
                    }
                }
                else {
                    getBean(beanName);
                }
            }
        }

        // 触发所有适用bean的初始化后回调。.
        for (String beanName : beanNames) {
            Object singletonInstance = getSingleton(beanName);
            if (singletonInstance instanceof SmartInitializingSingleton) {
                final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
                if (System.getSecurityManager() != null) {
                    AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                        smartSingleton.afterSingletonsInstantiated();
                        return null;
                    }, getAccessControlContext());
                }
                else {
                    smartSingleton.afterSingletonsInstantiated();
                }
            }
        }
    }

finishRefresh

在Spring中还提供了Lifecycle,Lifecycle中包含了start/stop方法,实现此接口后Spring会保证在启动的时候调用其start方法开始生命周期,并在Spring结束的时候调用stop方法来结束生命周期,通常用来配置后台程序,在启动后一直运行。而ApplicationContext的初始化最后正是保证了这一功能的实现。

protected void finishRefresh() {
        // 清除上下文级资源缓存(例如扫描的ASM元数据)。
        clearResourceCaches();

        // 为此上下文初始化生命周期处理器。
        initLifecycleProcessor();

        // 首先将刷新传播到生命周期处理器。
        getLifecycleProcessor().onRefresh();

        // 发布最终事件。
        publishEvent(new ContextRefreshedEvent(this));

        
        LiveBeansView.registerApplicationContext(this);
    }

1.initLifecycleProcessor 

 当ApplicationContext启动或者停止的时候,它会通过LifecycleProcessor来与所有声明的bean的周期做状态更新,而在LifecycleProcessor的使用前首先需要初始化。

protected void initLifecycleProcessor() {
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
            this.lifecycleProcessor =
                    beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
            if (logger.isTraceEnabled()) {
                logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
            }
        }
        else {
            DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
            defaultProcessor.setBeanFactory(beanFactory);
            this.lifecycleProcessor = defaultProcessor;
            beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
            if (logger.isTraceEnabled()) {
                logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +
                        "[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
            }
        }
    }

2.onRefresh

启动所有实现了Lifecycle接口的bean。

public void onRefresh() {
        startBeans(true);
        this.running = true;
    }
private void startBeans(boolean autoStartupOnly) {
        Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
        Map<Integer, LifecycleGroup> phases = new HashMap<>();
        lifecycleBeans.forEach((beanName, bean) -> {
            if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
                int phase = getPhase(bean);
                LifecycleGroup group = phases.get(phase);
                if (group == null) {
                    group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
                    phases.put(phase, group);
                }
                group.add(beanName, bean);
            }
        });
        if (!phases.isEmpty()) {
            List<Integer> keys = new ArrayList<>(phases.keySet());
            Collections.sort(keys);
            for (Integer key : keys) {
                phases.get(key).start();
            }
        }
    }

3.publishEvent

当完成ApplicationContext初始化的时候,需要通过Spring中的事件发布机制来发出ContextRefreshedEvent事件,以保证对应的监听器可以做进一步的逻辑处理。

protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
        Assert.notNull(event, "Event must not be null");

        // 如果需要,将事件装饰为ApplicationEvent
        ApplicationEvent applicationEvent;
        if (event instanceof ApplicationEvent) {
            applicationEvent = (ApplicationEvent) event;
        }
        else {
            applicationEvent = new PayloadApplicationEvent<>(this, event);
            if (eventType == null) {
                eventType = ((PayloadApplicationEvent) applicationEvent).getResolvableType();
            }
        }

        // 如果可能的话,现在就进行多播——或者在初始化多播后进行延迟
        if (this.earlyApplicationEvents != null) {
            this.earlyApplicationEvents.add(applicationEvent);
        }
        else {
            getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
        }

        // 也通过父上下文发布事件…
        if (this.parent != null) {
            if (this.parent instanceof AbstractApplicationContext) {
                ((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
            }
            else {
                this.parent.publishEvent(event);
            }
        }
    }

参考:《Spring源码深度解析》 郝佳 编著:

posted on 2019-01-04 16:53  AoTuDeMan  阅读(306)  评论(0编辑  收藏  举报

导航