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 定义信息名称,赋值到一个新的集合中 List3、总结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
如果设置了lazy-init=false(默认false),则容器在完成Bean定义的注册之后,会通过getBean方法,触发对指定Bean的初始化和依赖注入过程,这样当应用第一次向容器索取所需的Bean时,容器不再需要对Bean进行初始化和依赖注入,直接缓存中取,这样就提高了第一次获取Bean的性能。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)