初始化非延迟加载单例
完成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源码深度解析》 郝佳 编著: