前言 可以说前面的都是准备工作,而接下来开始的才是重点,在这一步会完成 BeanFactory 的初始化,同时实例化单例 Bean。
具体怎么操作的,那就一起阅读源码吧!
不过在阅读源码之前,还是需要了解一些知识的。
什么是 FactoryBean ?
FactoryBean 是如何使用的 ?
Bean 是如何初始化的?
常说的循环依赖是怎么解决的?
什么是 FactoryBean ? 在官网的这篇文章《What’s a FactoryBean?》 中有相关解答,有兴趣的小伙伴可以看一下。
由内部使用的对象实现的接口,这些对象 BeanFactory 本身就是单个对象的工厂。如果 bean 实现此接口,则它将用作对象公开的工厂,而不是直接用作将自身公开的 bean 实例。
注意:实现此接口的 bean 不能用作普通 bean。 FactoryBean以 bean 样式定义,但是为 bean 引用(getObject())公开的对象始终是它创建的对象。
FactoryBeans 可以支持单例和原型,并且可以按需延迟创建对象,也可以在启动时急于创建对象。
当生命一个 FactoryBean 时,会存在两个类型的 Bean,分别是 FactoryBean 本身,以及它需要创建的类型的 Bean。
下面是使用示例:
使用 1. PaidComponent public class PaidComponent { public PaidComponent () { System.out.println("PaidComponent 无参构造被调用" ); } }
2. PaidComponentFactoryBean @Component public class PaidComponentFactoryBean implements FactoryBean <PaidComponent > { @Override public PaidComponent getObject () throws Exception { System.out.println("PaidComponentFactoryBean 的 getObject 方法被调用" ); return new PaidComponent(); } @Override public Class<?> getObjectType() { return PaidComponent.class; } }
3 Test public class AnnotationConfigApplicationTest { public static void main (String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.register(JavaConfig.class); context.refresh(); System.out.println(context.getBean("paidComponentFactoryBean" )); System.out.println(context.getBean("&paidComponentFactoryBean" )); System.out.println(context.getBean(PaidComponent.class)); } }
可以看出注册了两个 Bean, 一个是 paidComponentFactoryBean
,另一个是 &paidComponentFactoryBean
。
而直接获取 paidComponentFactoryBean
获取到的其实是 FactoryBean 的 getObject()
方法返回的类型。
finishBeanFactoryInitialization 源码 protected void finishBeanFactoryInitialization (ConfigurableListableBeanFactory beanFactory) { 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)); } if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false , false ); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); } beanFactory.setTempClassLoader(null ); beanFactory.freezeConfiguration(); beanFactory.preInstantiateSingletons(); }
这里重点关注最后一行
beanFactory.preInstantiateSingletons();
preInstantiateSingletons 这块进入的是类 DefaultListableBeanFactory
类的源码。
public void preInstantiateSingletons () throws BeansException { if (logger.isTraceEnabled()) { logger.trace("Pre-instantiating singletons in " + this ); } List<String> beanNames = new ArrayList<>(this .beanDefinitionNames); for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { if (isFactoryBean(beanName)) { Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { FactoryBean<?> factory = (FactoryBean<?>) bean; 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 { getBean(beanName); } } } for (String beanName : beanNames) { Object singletonInstance = getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { StartupStep smartInitialize = this .getApplicationStartup().start("spring.beans.smart-initialize" ) .tag("beanName" , beanName); SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null ) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { smartSingleton.afterSingletonsInstantiated(); return null ; }, getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } smartInitialize.end(); } } }
上面方法中通过循环 beanNames
进行初始化 Bean。
其中需要区别 BeanFactory 和 普通 Bean。 这也是我开始为什么先介绍了什么是 BeanFactory ?
下面就需要重点关注 getBean(beanName)
方法。
getBean public Object getBean (String name) throws BeansException { return doGetBean(name, null , null , false ); }
在 getBean
方法中调用的是 doGetBean
方法。
doGetBean doGetBean 方法作用是:返回一个实例,该实例可以是指定bean的共享或独立的
。
该方法接受四个参数:
name – 要检索的 bean 的名称 requiredType – 要检索的 bean 的必需类型,这个可以为空 args –使用显式参数创建bean实例时要使用的参数(仅在创建新实例而不是检索现有实例时才应用) typeCheckOnly –是否为类型检查而不是实际使用获取实例
protected <T> T doGetBean ( String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException { String beanName = transformedBeanName(name); Object bean; Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null ) { if (logger.isTraceEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference" ); } else { logger.trace("Returning cached instance of singleton bean '" + beanName + "'" ); } } bean = getObjectForBeanInstance(sharedInstance, name, beanName, null ); } else { if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean( nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null ) { return (T) parentBeanFactory.getBean(nameToLookup, args); } else if (requiredType != null ) { return parentBeanFactory.getBean(nameToLookup, requiredType); } else { return (T) parentBeanFactory.getBean(nameToLookup); } } if (!typeCheckOnly) { markBeanAsCreated(beanName); } StartupStep beanCreation = this .applicationStartup.start("spring.beans.instantiate" ) .tag("beanName" , name); try { if (requiredType != null ) { beanCreation.tag("beanType" , requiredType::toString); } RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); 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); } } } if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) { Object prototypeInstance = null ; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { String scopeName = mbd.getScope(); if (!StringUtils.hasLength(scopeName)) { throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'" ); } Scope scope = this .scopes.get(scopeName); if (scope == null ) { throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'" ); } try { Object scopedInstance = scope.get(beanName, () -> { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new ScopeNotActiveException(beanName, scopeName, ex); } } } catch (BeansException ex) { beanCreation.tag("exception" , ex.getClass().toString()); beanCreation.tag("message" , String.valueOf(ex.getMessage())); cleanupAfterBeanCreationFailure(beanName); throw ex; } finally { beanCreation.end(); } } if (requiredType != null && !requiredType.isInstance(bean)) { try { T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); if (convertedBean == null ) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return convertedBean; } catch (TypeMismatchException ex) { if (logger.isTraceEnabled()) { logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'" , ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean; }
上面代码比较长,基本上步骤已经添加相应的注释,基本上可以分为三步:
从缓存中获取到 Bean,创建对应的 Bean;
没有从缓存中获取到 Bean,创建对应的 Bean;
检查所需的类型是否与实际bean实例的类型匹配。
下面从这三个步骤分别介绍:
Object sharedInstance = getSingleton(beanName);
public Object getSingleton (String beanName) { return getSingleton(beanName, true ); } @Nullable protected Object getSingleton (String beanName, boolean allowEarlyReference) { Object singletonObject = this .singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { singletonObject = this .earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { synchronized (this .singletonObjects) { singletonObject = this .singletonObjects.get(beanName); if (singletonObject == null ) { singletonObject = this .earlySingletonObjects.get(beanName); if (singletonObject == null ) { ObjectFactory<?> singletonFactory = this .singletonFactories.get(beanName); if (singletonFactory != null ) { singletonObject = singletonFactory.getObject(); this .earlySingletonObjects.put(beanName, singletonObject); this .singletonFactories.remove(beanName); } } } } } } return singletonObject; }
这里可以看出,获取一个 Bean :
先从 singletonObjects
中获取 Bean;
获取不到,从 earlySingletonObjects
中获取 Bean;
获取不到,从 singletonFactories
中获取 Bean。
当然这一块涉及到循环引用,篇幅有限,后面会专门介绍循环引用。
没有从缓存中获取到 Bean,创建对应的 Bean
if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) { } else { String scopeName = mbd.getScope(); }
总结 这里主要介绍了 Bean 的创建过程,主要是对整个过程有个大概的了解和熟悉,针对过程画图如下:
其中 Bean 的实例化主要关注单例 Bean 的实例化,后面准备对其进行详细研究后,再进行说明。
相关推荐