深入理解Spring系列之六:bean初始化
2017-08-10 20:41
676 查看
《深入理解Spring系列之四:BeanDefinition装载前奏曲》中提到,对于非延迟单例bean的初始化在finishBeanFactoryInitialization(beanFactory)中完成。进入这个方法,代码如下。
关注最后一行代码,
从上面的代码中看到,只会对非延迟单例bean进行初始化,scope为其它值的bean会在使用到的时候进行初始化,如prototype。这里关注getBean方法,这个方法看着很眼熟,其实就是《深入理解Spring系列之一:开篇》示例代码中用到的getBean,Spring对这个方法做了重复使用。getBean方法的具体实现在doGetBean方法中,这个方法的代码很长就不贴代码了。在doGetBean中,首先会初始化其依赖的bean,然后进行自身的初始化,这个方法里关注如下的代码段。
这段代码完成了单例bean的初始化,追踪代码进入doCreateBean方法中,在这个方法中进行bean实例的创建、属性填充、将bean实例加入单例bean实例的缓存中。doCreateBean方法中有如下代码段。
createBeanInstance方法里完成bean实例的创建,具体过程可继续追踪代码查看,其实就是使用反射进行实例对象的创建。
Java实战技术分享微信公众号:JavaQ,关注后及时获取更新!
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // Initialize conversion service for this context. 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); // Allow for caching all bean definition metadata, not expecting further changes. beanFactory.freezeConfiguration(); // Instantiate all remaining (non-lazy-init) singletons. beanFactory.preInstantiateSingletons(); }
关注最后一行代码,
beanFactory.preInstantiateSingletons()完成初始化所有非延迟的单例bean,进入这个方法的具体实现,代码如下。 public void preInstantiateSingletons() throws BeansException { if (this.logger.isDebugEnabled()) { this.logger.debug("Pre-instantiating singletons in " + this); } // Iterate over a copy to allow for init methods which in turn register new bean definitions. // While this may not be part of the regular factory bootstrap, it does otherwise work fine. List beanNames = new ArrayList(this.beanDefinitionNames); // Trigger initialization of all non-lazy singletonbeans... 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() { @Override public Boolean run() { return ((SmartFactoryBean) factory).isEagerInit(); } }, getAccessControlContext()); }else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); } }else { getBean(beanName); } } } // Trigger post-initialization callback for all applicable beans... 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() { @Override public Object run() { smartSingleton.afterSingletonsInstantiated(); return null; } }, getAccessControlContext()); }else { smartSingleton.afterSingletonsInstantiated(); } } } }
从上面的代码中看到,只会对非延迟单例bean进行初始化,scope为其它值的bean会在使用到的时候进行初始化,如prototype。这里关注getBean方法,这个方法看着很眼熟,其实就是《深入理解Spring系列之一:开篇》示例代码中用到的getBean,Spring对这个方法做了重复使用。getBean方法的具体实现在doGetBean方法中,这个方法的代码很长就不贴代码了。在doGetBean中,首先会初始化其依赖的bean,然后进行自身的初始化,这个方法里关注如下的代码段。
// Create bean instance. if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, new ObjectFactory() { @Override public Object getObject() throws BeansException { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that receiveda temporary reference to the bean. destroySingleton(beanName); throw ex; } } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); }
这段代码完成了单例bean的初始化,追踪代码进入doCreateBean方法中,在这个方法中进行bean实例的创建、属性填充、将bean实例加入单例bean实例的缓存中。doCreateBean方法中有如下代码段。
if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); }
createBeanInstance方法里完成bean实例的创建,具体过程可继续追踪代码查看,其实就是使用反射进行实例对象的创建。
Java实战技术分享微信公众号:JavaQ,关注后及时获取更新!
相关文章推荐
- 深入理解Spring系列之三:BeanFactory解析
- Spring系列【11】配置Bean的初始化行为
- 深入理解Spring系列之九:DispatcherServlet初始化源码分析
- 深入理解Spring系列之七:web应用自动装配Spring配置
- 深入理解Spring4框架(三)——Bean
- 深入理解Spring系列之八:常用的扩展接口
- Spring系列之-Spring IOC容器设计:IOC容器初始化-Bean注册
- Spring学习(三)ioc工厂bean深入理解
- 分布式缓存技术redis学习系列----深入理解Spring Redis的使用
- Spring学习(三)ioc工厂bean深入理解
- 7.8.6: 深入理解容器中的Bean---强制初始化Bean
- 技术文章 | 分布式缓存技术redis学习系列----深入理解Spring Redis的使用
- 分布式缓存技术redis学习系列(六)—— 深入理解Spring Redis的使用
- Spring4深入理解IOC&DI02----Bean配置--自动装配、bean之间的继承与依赖、使用外部属性文件
- Spring应用、原理以及粗读源码系列(一)--框架总述、以Bean为核心的机制(IoC容器初始化以及依赖注入)
- spring学习之---深入理解容器中的Bean
- 深入理解MySQL 5.7 GTID系列(六):MySQL启动初始化GTID模块
- 分布式缓存技术redis学习系列----深入理解Spring Redis的使用
- 深入理解Spring系列之十:DispatcherServlet请求分发源码分析
- 深入理解Spring系列之一:开篇