spring源码--07--IOC高级特性--lazy-init实现预实例化

spring源码--07--IOC高级特性--lazy-init实现预实例化,第1张

spring源码--07--IOC高级特性--lazy-init实现预实例化 spring源码–07–IOC高级特性–lazy-init实现预实例化
1、开始位置
   
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
		

   @Override 
	// 在创建IOC容器前,如果已经有容器存在,则需要把已有的容器销毁和关闭,在重新建立新容器。
	// 在新建立的容器中,对容器进行初始化,对BeanDefinition资源进行载入
    public void refresh() throws BeansException, IllegalStateException {
   
            
				·
				·
				·
				·
				·
				·
                
                // 初始化所有剩余的单例Bean
				// 这里是对容器lazy-init属性进行处理的入口方法  
                finishBeanFactoryInitialization(beanFactory);
                
				·
				·
				·
				·
				·
				·
     

	}
}
2、finishBeanFactoryInitialization() 源码
    对注册后的Bean进行预实例化所谓预实例化就是DI,也就是调用getBean方法


public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
		

	//对配置了lazy-init属性的Bean进行预实例化处理  
	// lazy-init 默认false, 即Spring默认就是预实例化
	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		
		//这是Spring3以后新加的代码,为容器指定一个转换服务(ConversionService) ,对某些Bean属性进行转换时使用
		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));
		}

 
		// 如果之前未注册任何bean后置处理器(如 PropertyPlaceholderConfigurer bean),请注册默认嵌入值的 解析器:主要用于解析注解属性
		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);

	 
		//缓存容器中所有注册的BeanDefinition元数据,以防被修改  
		beanFactory.freezeConfiguration();

		// Instantiate all remaining (non-lazy-init) singletons.
		//对配置了lazy-init属性的单态模式Bean进行预实例化处理  
		beanFactory.preInstantiateSingletons();
	}
	
	
 
	
	
}

2、DefaultListableBeanFactory

ConfigurableListableBeanFactory是一个接口,preInstantiateSingletons方法由子类DefaultListableBeanFactory实现。

2.1、主要源码
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
		implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
			
	@Override
	//对配置lazy-init属性 单例Bean的预实例化  
	public void preInstantiateSingletons() throws BeansException {
		if (logger.isTraceEnabled()) {
			logger.trace("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.
		
		// 此处目的,把所有的 bean 定义信息名称,赋值到一个新的集合中
		List beanNames = new ArrayList<>(this.beanDefinitionNames);

		 
		// 触发所有non-lazy 单例bean的初始化 
		for (String beanName : beanNames) {
			//获取指定名称的Bean定义  
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			
			//Bean不是抽象的,是单例模式的,且lazy-init属性配置为false  
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				
				//如果指定名称的bean是创建容器的Bean,
				if (isFactoryBean(beanName)) {
					Object bean = getBean("&" + beanName);
					if (bean instanceof FactoryBean) {
						final FactoryBean factory = (FactoryBean) bean;
						// 是否渴望初始化
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged((PrivilegedAction)
											((SmartFactoryBean) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean) factory).isEagerInit());
						}
						if (isEagerInit) {
							getBean(beanName);
						}
					}
				}
				else {
					//依赖注入,也就是DI
					getBean(beanName);
				}
			}
		}

 
		// 触发所有applicable 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) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}
	
	
}
 
3、总结 

如果设置了lazy-init=false(默认false),则容器在完成Bean定义的注册之后,会通过getBean方法,触发对指定Bean的初始化和依赖注入过程,这样当应用第一次向容器索取所需的Bean时,容器不再需要对Bean进行初始化和依赖注入,直接缓存中取,这样就提高了第一次获取Bean的性能。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5709407.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)