spring的finishBeanFactoryInitialization方法分析
Posted 众妙之门
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring的finishBeanFactoryInitialization方法分析相关的知识,希望对你有一定的参考价值。
spring源码版本5.0.5
概述
该方法会实例化所有剩余的非懒加载单例 bean。除了一些内部的 bean、实现了 BeanFactoryPostProcessor 接口的 bean、实现了 BeanPostProcessor 接口的 bean,其他的非懒加载单例 bean 都会在这个方法中被实例化,并且 BeanPostProcessor 的触发也是在这个方法中。
分析
跟踪到AbstractApplicationContext.refresh()方法,找到代码finishBeanFactoryInitialization(beanFactory)查看实现。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // Initialize conversion service for this context. // 1.初始化此上下文的转换服务 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)); } // Register a default embedded value resolver if no bean post-processor // (such as a PropertyPlaceholderConfigurer bean) registered any before: // at this point, primarily for resolution in annotation attribute values. // 2.如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器:主要用于注解属性值的解析 if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. // 3.初始化LoadTimeWeaverAware Bean实例对象 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. // 4.冻结所有bean定义,注册的bean定义不会被修改或进一步后处理,因为马上要创建 Bean 实例对象了 beanFactory.freezeConfiguration(); // Instantiate all remaining (non-lazy-init) singletons. // 5.实例化所有剩余(非懒加载)单例对象 beanFactory.preInstantiateSingletons(); }
继续跟踪到DefaultListableBeanFactory#preInstantiateSingletons
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<String> beanNames = new ArrayList<>(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans... //遍历beanNames,触发所有非懒加载单例bean的初始化 for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); //Bean实例:不是抽象类 && 是单例 && 不是懒加载 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { //判断beanName对应的bean是否为FactoryBean if (isFactoryBean(beanName)) { //通过getBean(&beanName)拿到的是FactoryBean本身;通过getBean(beanName)拿到的是FactoryBean创建的Bean实例 Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { final FactoryBean<?> factory = (FactoryBean<?>) bean; //判断这个FactoryBean是否希望急切的初始化 boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); } } } else { //如果beanName对应的bean不是FactoryBean,只是普通Bean,通过beanName获取bean实例 getBean(beanName); } } } ...... }
要理解FactoryBean和Bean的区别
一般情况下,Spring 通过反射机制利用 bean 的 class 属性指定实现类来实例化 bean。而 FactoryBean 是一种特殊的 bean,它是个工厂 bean,可以自己创建 bean 实例,如果一个类实现了 FactoryBean 接口,则该类可以自己定义创建实例对象的方法,只需要实现它的 getObject() 方法。
注:很多中间件都利用 FactoryBean 来进行扩展。
引入了几个重要的缓存:
- mergedBeanDefinitions 缓存:beanName -> 合并的 bean 定义。
- beanDefinitionMap 缓存:beanName -> BeanDefinition。
- singletonObjects 缓存:beanName -> 单例 bean 对象。
- earlySingletonObjects 缓存:beanName -> 单例 bean 对象,该缓存存放的是早期单例 bean 对象,可以理解成还未进行属性填充、初始化。
- singletonFactories 缓存:beanName -> ObjectFactory。
- singletonsCurrentlyInCreation 缓存:当前正在创建单例 bean 对象的 beanName 集合。
继承跟踪到AbstractBeanFactory#doGetBean创建bean
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { //解析beanName,主要是解析别名、去掉FactoryBean的前缀“&” final String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. //尝试从缓存中获取beanName对应的实例,通过缓存解决循环依赖问题 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (logger.isDebugEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.debug("Returning eagerly cached instance of singleton bean ‘" + beanName + "‘ that is not fully initialized yet - a consequence of a circular reference"); } else { logger.debug("Returning cached instance of singleton bean ‘" + beanName + "‘"); } } //返回beanName对应的实例对象(主要用于FactoryBean的特殊处理,普通Bean会直接返回sharedInstance本身) bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // Fail if we‘re already creating this bean instance: // We‘re assumably within a circular reference. // scope为prototype非单例的循环依赖校验:如果beanName已经正在创建Bean实例中,而此时我们又要再一次创建beanName的实例,则代表出现了循环依赖,需要抛出异常。 // 例子:如果存在A中有B的属性,B中有A的属性,那么当依赖注入的时候,就会产生当A还未创建完的时候因为对于B的创建再次返回创建A,造成循环依赖 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory. BeanFactory parentBeanFactory = getParentBeanFactory(); //如果parentBeanFactory存在,并且beanName在当前BeanFactory不存在Bean定义,则尝试从parentBeanFactory中获取bean实例 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean( nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null) { // Delegation to parent with explicit args. return (T) parentBeanFactory.getBean(nameToLookup, args); } else { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } } if (!typeCheckOnly) { //如果不是仅仅做类型检测,而是创建bean实例,这里要将beanName放到alreadyCreated缓存 markBeanAsCreated(beanName); } try { final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. //拿到当前bean依赖的bean名称集合,在实例化自己之前,需要先实例化自己依赖的bean,如使用@DependsOn String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between ‘" + beanName + "‘ and ‘" + dep + "‘"); } registerDependentBean(dep, beanName); try { getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "‘" + beanName + "‘ depends on missing bean ‘" + dep + "‘", ex); } } } // Create bean instance. if (mbd.isSingleton()) { //scope为singleton的bean创建(新建了一个ObjectFactory,并且重写了getObject方法,在里面创建bean sharedInstance = getSingleton(beanName, () -> { 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 received a temporary reference to the bean. destroySingleton(beanName); throw ex; } }); //返回beanName对应的实例对象 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } //其它非单例的情况,暂不分析 ...... } catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); throw ex; } } ...... return (T) bean; }
查看DefaultSingletonBeanRegistry#getSingleton
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "Bean name must not be null"); synchronized (this.singletonObjects) { //首先检查beanName对应的bean实例是否在缓存中存在,如果已经存在,则直接返回 Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { if (this.singletonsCurrentlyInDestruction) { throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction " + "(Do not request a bean from a BeanFactory in a destroy method implementation!)"); } if (logger.isDebugEnabled()) { logger.debug("Creating shared instance of singleton bean ‘" + beanName + "‘"); } //创建单例前的操作,把bean放入正准备创建的一个Set中singletonsCurrentlyInCreation,如果重复会报异常 //如果存在构造器循环依赖的时候(A(B b),B(C c),C(A a)),会在这点报出异常 beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); } try { //执行singletonFactory的getObject方法获取bean实例,就是执行传入方法createBean singletonObject = singletonFactory.getObject(); newSingleton = true; } ...... finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; } //创建单例后的操作,在singletonsCurrentlyInCreation中移除 afterSingletonCreation(beanName); } if (newSingleton) { addSingleton(beanName, singletonObject); } } return singletonObject; } }
继承跟踪AbstractAutowireCapableBeanFactory#createBean
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { ...... try { //验证及准备覆盖的方法(对override属性进行标记及验证) mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. //实例化前的处理,如果有实现InstantiationAwareBeanPostProcessor的BeanPostProcessor可以直接返回真正的bean实例 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } try { //创建Bean实例(一般真正创建Bean的方法) Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean ‘" + beanName + "‘"); } return beanInstance; } ...... }
实例化前的处理,给 InstantiationAwareBeanPostProcessor 一个机会返回代理对象来替代真正的 bean 实例,从而跳过 Spring 默认的实例化过程,达到“短路”效果。会执行 InstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation 方法,该方法可以返回 bean 实例的代理,从而跳过 Spring 默认的实例化过程。
以上是关于spring的finishBeanFactoryInitialization方法分析的主要内容,如果未能解决你的问题,请参考以下文章
你了解Spring从Spring3到Spring5的变迁吗?
学习笔记——Spring简介;Spring搭建步骤;Spring的特性;Spring中getBean三种方式;Spring中的标签