• Spring源码情操陶冶-AbstractApplicationContext#finishBeanFactoryInitialization


    承接前文Spring源码情操陶冶-AbstractApplicationContext#registerListeners
    约定web.xml配置的contextClass为默认值XmlWebApplicationContext

    AbstractRefreshableWebApplicationContext#finishBeanFactoryInitialization()

    笔者直接去查看相应的的源码

    	/**
    	 * Finish the initialization of this context's bean factory,
    	 * initializing all remaining singleton beans.
    	 */
    	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();
    	}
    

    从上述的注释可知,spring会提前初始化那些作用域为singleton类型的bean对象,当然并不包括lazy-init属性的bean对象

    DefaultListableBeanFactory#preInstantiateSingletons()

    具体实现preInstantiateSingletons()方法便只有DefaultListableBeanFactory类,直接去翻阅代码

    public void preInstantiateSingletons() throws BeansException {
    		if (this.logger.isDebugEnabled()) {
    			this.logger.debug("Pre-instantiating singletons in " + this);
    		}
    
    		//获取解析过的所有beanNames
    		List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
    
    		// Trigger initialization of all non-lazy singleton beans...
    		for (String beanName : beanNames) {
    			//获取对应的RootBeanDefinition,其内部就含有BeanDefinition
    			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
    			//非抽象、单例模式、非lay-init,满足以上条件的进入到实例化(默认情况下Bean为singleton单例模式)
    			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
    				//对FactoryBean的类型实例化
    				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的实例化
    					getBean(beanName);
    				}
    			}
    		}
    		// Trigger post-initialization callback for all applicable beans...
    		for (String beanName : beanNames) {
    			//获取上述的实例化的静态对象,如果为SmartInitializingSingleton的实现类进行afterSingletonInstantiated()方法调用
    			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 {
                                            //会调用InitializingBean的afterPropertiesSet()方法
    					smartSingleton.afterSingletonsInstantiated();
    				}
    			}
    		}
    

    笔者提示这里的实例化指的是对beanFactory中beanName对应的RootBeanDefinition中的beanClass进行准确的实例化,包括属性以及方法复用等等,主要是通过DefaultListableBeanFactory#getBean()方法,因为其很复杂,我们后续再分析

    需要注意的是,默认情况下Bean对象的作用域一般为singleton,所以默认情况下bean工厂上的bean都会进行实例化。除了以下情况先不参与
    1.使用@Lazy注解修饰Bean对象,指定@Lazy(value=true)

    2.使用@Scope注解修饰Bean对象,指定@Scope(value="prototype")

    小结

    1. 主要是实例化RootDefinition中的beanClass类,并完成相应的属性设置,方法调用等等(默认情况下Bean的Scope类型为singleton单例模式)。即使当中的属性如果没有提前被初始化的话,其也会被调用getBean()方法来进行初始化后再被设置

    2. 调用所有实现InitializingBean接口的afterPropertiesSet()方法

    3. 调用BeanPostProcessors接口,比如postProcessBeforeInitialization()postProcessAfterInitialization()实例化前后方法。其中涉及@Resource@Autowired等注解的解析并进行相应的实例注入

    4. 此处插一句:BeanPostProcessors接口处理,优先处理InstantiationAwareBeanPostProcessor.class接口实现类,一旦其内部方法postProcessBeforeInstantiation(Class,String)执行后返回null,则不执行postProcessAfterInitialization()方法;随后处理其他BeanPostProcessor接口的postProcessBeforeInitialization()postProcessAfterInitialization()方法

    附上springBean的生命周期图(含lazy-init的Bean)
    springbean_lifecycle

    上图示的第八步骤与第九步骤需要替换下,通过阅读源码发现执行InitializingBean#afterPropertiesSet()前还得优先执行BeanPostProcessors集合的postProcessBeforeInitialization()方法,也就是设置ApplicationContext以及Environment变量均在InitializingBean前

    Bean销毁的触发机制:

    1.实例化@Scope(value="singleton")类型的Bean对象过程中(默认),如果出现异常则会执行AbstractBeanFactory#destorySingleton()方法,当然也支持直接调用

    2.在上述销毁的过程中也会去默认执行@Scope(value="prototype")类型Bean的close/destory()方法(倘若存在)

    3.同样在上述的销毁过程中,如果对应的Bean对象为DisposableBean类型,则会调用destory()方法来进行销毁操作

    Bean对象中指定Scope为singletonprototype的小区别

    1.前者是指定Bean对象为单例模式, 即初始化一次后便会保存在内存中,专门由相应的集合去保存;后者则是实例模式,在主动销毁以及被动被回收之后再获取的时候则会被新建

    2.前者是Spring的默认模式,后者是需要用户去指定的。前者比较节省资源

    3.前者进行销毁时,优先先销毁依赖此Bean的Bean集合,然后再销毁自己,最后再销毁其内含的关联Bean属性;后者想销毁要么直接调用对应的销毁方法要么就是被前者波及进行销毁

    下节预告

    Spring源码情操陶冶-AbstractApplicationContext#finishRefresh

  • 相关阅读:
    备份恢复八大核心
    ORACLE CentOS5.6安装
    ORA-00205
    sf02_选择排序算法Java与Python实现
    解决SQL命令行回退的问题
    redhat 6.4 yum 本地配置简记
    ORA-12705: Cannot access NLS data files or invalid environment specified
    asmca无法创建ASM磁盘
    Sort List
    Merge k Sorted Lists
  • 原文地址:https://www.cnblogs.com/question-sky/p/6850309.html
Copyright © 2020-2023  润新知