此至,ApplicationContext 已经完成了所有的准备工做,开始初始化剩余的 bean 了(第 11 步)。java
public void refresh() throws BeansException, IllegalStateException { // 11. 初始化剩余的 bean (部分在 invokeBeanFactoryPostProcessors 已经初始化) finishBeanFactoryInitialization(beanFactory); }
finishBeanFactoryInitialization 主要是实例化非懒加载的 bean。git
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(); }
(1) String2DateConvertergithub
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) 注册spring
注意:beanName 必须为 conversionServiceapp
<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) 测试ide
@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(); } } } }
天天用心记录一点点。内容也许不重要,但习惯很重要!this