企业网站代码模板陕西百度推广的代理商
前言
前面几章spring已经把需要的注册的bean的信息已经全部加载到了BeanFactory中了,那么之后要做的事儿当然就是进行实例化了,当然了可能有人会问为何不在加载到bean信息的时候直接进行实例化呢,这不还需要依赖注入嘛,当然是要所有的都加载完了才能实例化。ApplicationContext相对于BeanFactory来说,早期的BeanFactory受制于硬件配置,所以在我们需要某个bean的时候才会进行实例化。而ApplicationContext则会在一开始就将所有的注册的Bean(标记懒加载的,或者非单例加载除外)全部进行实例化。本文则主要介绍spring如何实例化bean,并且Bean的生命周期也会穿插其中。
这儿先放一张加载的大致流程图
从图中可以看到加正式加载的过程并不多,实例化->放入提前暴露容器->赋值完成后其实就算完成实例化了,但spring在其中穿插了 很多的BeanPostProcessor以及aware,同时也会根据所加载bean是否实现了InitializingBean接口来决定是否需要执行afterPropertiesSet方法。说明spring在实例化bean时给我们流下了足够的扩展空间。
正文
我们回到上下文的refresh方法中
public void refresh() throwsBeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {
../代码略try{
postProcessBeanFactory(beanFactory);
invokeBeanFactoryPostProcessors(beanFactory);//注册所有BeanPostProcessors
registerBeanPostProcessors(beanFactory);
../代码略//实例化bean
finishBeanFactoryInitialization(beanFactory);
../代码略
}
../代码略
}
}
前面一篇我们成功的执行了invokeBeanFactoryPostProcessors方法,然后将所有的BeanFactoryPostProcessor后置方法执行了,然后也成功的将所有需要注册到容器的bean的BeanDefination也收集到了BeanFactory中。本文则主要关注后面两个方法。
registerBeanPostProcessors 按照一定顺序注册BeanPostProcessor
实例化所有的bean
至于注册BeanPostProcessor较为简单,就是将系统所有的BeanPostProcessor按照顺序,即我们之前也遇到的三级顺序来添加,实现了PriorityOrdered为第一级,实现了Ordered为第二级,其他的为第三级。具体添加过程较为简单所以代码部分略过,我们直接看实例化bean的方法
1.finishBeanFactoryInitialization 实例化的入口
protected voidfinishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {//初始化一个ConversionService
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));
}//初始化一个默认的EmbeddedValueResolver(如果系统没有指定的话)
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal->getEnvironment().resolvePlaceholders(strVal));
}//实例化LoadTimeWeaverAware getBean方法会触发实例化
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);//实例化之前冻结配置
beanFactory.freezeConfiguration();//实例化所有非懒加载的实例
beanFactory.preInstantiateSingletons();
}
这儿就是做了一些必要的提前设置。这儿我们进入beanFactory.preInstantiateSingletons方法,注意这儿的beanFactory一般为DefaultListableBeanFactory,本系列第二章初始化应用上下文有讲到
2.preInstantiateSingletons
顾名思义,看方法名就知道是实例化之前的一些准备,看代码
@Overridepublic void preInstantiateSingletons() throwsBeansException {//打印下日志
if (this.logger.isDebugEnabled()) {this.logger.debug("Pre-instantiating singletons in " + this);
}//迭代spring找到的所有需要注册的bean
List beanNames = new ArrayList<>(this.beanDefinitionNames);//开始迭代
for(String beanName : beanNames) {//获取该bean对应的mergedBeanDefinition//如果没有则获取其父类的MergedLocalBeanDefinition//如果父类为空则创建RootBeanDefinition
RootBeanDefinition bd =getMergedLocalBeanDefinition(beanName);//如果不是抽象类 且是单例构造 非懒加载 则实例化
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {//如果该bean是FactoryBean
if(isFactoryBean(beanName)) {//如果是FactoryBean则要判断下其是否需要提早初始化
Object bean = getBean(FACTORY_BEAN_PREFIX +beanName);if (bean instanceofFactoryBean) {final FactoryBean> factory = (FactoryBean>) bean;booleanisEagerInit;if (System.getSecurityManager() != null && factory instanceofSmartFactoryBean) {
isEagerInit= AccessController.doPrivileged((PrivilegedAction)
((SmartFactoryBean>) factory)::isEagerInit,
getAccessControlContext());
}else{
isEagerInit= (factory instanceof SmartFactoryBean &&((SmartFactoryBean>) factory).isEagerInit());
}if(isEagerInit) {
getBean(beanName);
}
}
}else{//非factoryBean 初始化
getBean(beanName);
}
}
}//如果为SmartInitializingSingleton类型 则执行下其初始化完成后的afterSingletonsInstantiated方法
for(String beanName : beanNames) {
Object singletonInstance=getSingleton(beanName);if (singletonInstance instanceofSmartInitializingSingleton) {final SmartInitializingSingleton smartSingleton =(SmartInitializingSingleton) singletonInstance;if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction) () ->{
smartSingleton.afterSingletonsInstantiated();return null;
}, getAccessControlContext());
}else{
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
方法也就是获取我们之前得到的beanDefinitionNames,然后挨个遍历,如果其不为抽象类,且是单例加载,非延迟加载,那我们就对其进行实例化。然后根据beanName获取其合并的BeanDefinition,也就是其BeanDefinition一直递归加上其父类的BeanDefinition,最终合并为一个RootBeanDefinition并返回,具体的这儿的分析可以查看这篇博客。https://blog.csdn.net/andy_zhang2007/article/details/86514320
获取到合并的beanDefinition后,检查其是否满足加载的条件。这儿可以看出springboot满足初始化即加载的条件主要由两:单例记载,非懒加载。
然后会判断当前迭代的bean是否是FactoryBean,如果是则进行特殊判断处理下,这儿二者最终都会调用getBean方法来创建类。创建完成后如果该bean实现了SmartInitializingSingleton接口,则会执行下其afterSingletonsInstantiated方法。
其getBean方法是主要的创建方法,其实看到这儿也能发现。ApplicationContext方法的初始即实例化最终也是循环调用的BeanFactory的getBean方法。
3.getBean
protected T doGetBean(final String name, @Nullable final ClassrequiredType,
@Nullablefinal Object[] args, boolean typeCheckOnly) throwsBeansException {//获取beanName
final String beanName =transformedBeanName(name);
Object bean;//找下是否已经创建过
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 + "'");
}
}//直接拿出来并返回
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}//这儿则是创建流程
else{//重复声明时有可能出现此问题
if(isPrototypeCurrentlyInCreation(beanName)) {throw newBeanCurrentlyInCreationException(beanName);
}//查看父BeanFactory是否已经有了 如果有的话则返回父BeanFactory中的实例
BeanFactory parentBeanFactory =getParentBeanFactory();if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {//Not found -> check parent.
String nameToLookup =originalBeanName(name);if (parentBeanFactory instanceofAbstractBeanFactory) {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.
returnparentBeanFactory.getBean(nameToLookup, requiredType);
}
}//标记该bean已经在开始被实例化
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}try{//获取合并BeanDefinition
final RootBeanDefinition mbd =getMergedLocalBeanDefinition(beanName);//检查下合并BeanDefinition 这儿主要检查是否为抽象类
checkMergedBeanDefinition(mbd, beanName, args);//获取该bean的构造函数的参数//如果该bean构造函数中依赖的参数中,有参数实例化也需要依赖该bean 那么直接报循环引用的错误
String[] dependsOn =mbd.getDependsOn();if (dependsOn != null) {for(String dep : dependsOn) {if(isDependent(beanName, dep)) {throw newBeanCreationException(mbd.getResourceDescription(), beanName,"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}//如果没有循环引用也直接先实例化其依赖
registerDependentBean(dep, beanName);try{
getBean(dep);
}catch(NoSuchBeanDefinitionException ex) {throw newBeanCreationException(mbd.getResourceDescription(), beanName,"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}//如果为scope为sington 那么只创建一个
if(mbd.isSingleton()) {
sharedInstance= getSingleton(beanName, () ->{try{returncreateBean(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);throwex;
}
});
bean=getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}//如果为scope为Prototype 那么每次都创建个新的
else if(mbd.isPrototype()) {//It's a prototype -> create a new instance.
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();final 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{returncreateBean(beanName, mbd, args);
}finally{
afterPrototypeCreation(beanName);
}
});
bean=getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}catch(IllegalStateException ex) {throw newBeanCreationException(beanName,"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}catch(BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);throwex;
}
}//如果有合适的Converter 那么执行下converter转换器的操作 返回转换后的实例
if (requiredType != null && !requiredType.isInstance(bean)) {try{
T convertedBean=getTypeConverter().convertIfNecessary(bean, requiredType);if (convertedBean == null) {throw newBeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}returnconvertedBean;
}catch(TypeMismatchException ex) {if(logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +ClassUtils.getQualifiedName(requiredType)+ "'", ex);
}throw newBeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}return(T) bean;
}
该方法内容较多,但可以分步看
判断是否已经创建中并能获取实例,如果可以就返回,否则下一步
判断一下重复加载的问题,然后查看父BeanFactory是否有该类,如果有则使用父类的getBean返回,否则下一步
判断下循环循环引用的问题,如果构造函数有参数,但不存在循环引用,则先实例化构造参数
最终根据bean的scope来确定不同的初始化方式
根据初始化完成后的bean来寻找是否有合适的converter,如果有则转换后返回,否则直接返回
这样拆开看发现也就是spring很常规的一个判断逻辑,由于不同scope只是创建的数量不一致,但是实例化bean是一致的,所以我们就直接看实例化singleton,也就是我们最常见的单例注册。
4.单例化代码的片段
上面的代码中,我们着重看下创建单例的代码片段。
if(mbd.isSingleton()) {//获取创建后的实例
sharedInstance = getSingleton(beanName, () ->{try{//回调函数创建bean
returncreateBean(beanName, mbd, args);
}catch(BeansException ex) {//出现异常则将其销毁
destroySingleton(beanName);throwex;
}
});//看当前的bean是一个普通的bean还是beanFactory//如果是普通的bean直接返回//如果是factoryBean则返回其getObject方法的结果
bean =getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
这儿可以看到通过getSingletom方法获取bean,这个方法有个回调函数是用来创建bean的,可以得知具体创建bean的时机肯定是getSingleton中调用这个函数的时候。getSingletom则只是做了一些前后处理。那我们还是先看下回调函数中的createBean方法,毕竟这才是核心创建过程。
5.createBean
protectedObject createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throwsBeanCreationException {//获取该bean的合并BeanDefinition
RootBeanDefinition mbdToUse =mbd;//查看当前RootBeanDefinition是否已经有resolveBeanClass 如果有的话直接clone一个beanDefinition
Class> resolvedClass =resolveBeanClass(mbd, beanName);if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse= newRootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}//检查下所有的override方法
try{
mbdToUse.prepareMethodOverrides();
}catch(BeanDefinitionValidationException ex) {throw newBeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName,"Validation of method overrides failed", ex);
}try{//执行所有实现了InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法//这儿如果返回不为null 则就是自定义了返回的bean逻辑
Object bean =resolveBeforeInstantiation(beanName, mbdToUse);if (bean != null) {returnbean;
}
}catch(Throwable ex) {throw newBeanCreationException(mbdToUse.getResourceDescription(), beanName,"BeanPostProcessor before instantiation of bean failed", ex);
}try{//执行doCreateBean创建bean
Object beanInstance =doCreateBean(beanName, mbdToUse, args);if(logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}returnbeanInstance;
}
../代码省略
}
该方法内部照例做了一下准备,其中有个方法需要注意resolveBeforeInstantiation ,该方法会在实例化之前执行所有实现了InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法,如果返回值不为空则代表自定义了类实例化过程,这样会直接返回bean而不会进行下面的所有操作。
然后执行doCreateBean创建实例对象。
6.doCreateBean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final@Nullable Object[] args)throwsBeanCreationException {//实例化bean 如果factoryBeanInstance已经有了则将其remove掉
BeanWrapper instanceWrapper = null;if(mbd.isSingleton()) {
instanceWrapper= this.factoryBeanInstanceCache.remove(beanName);
}if (instanceWrapper == null) {//创建实例
instanceWrapper =createBeanInstance(beanName, mbd, args);
}final Object bean =instanceWrapper.getWrappedInstance();
Class> beanType =instanceWrapper.getWrappedClass();//检查下创建出来的bean是否为null,例如我们从beanFactory中get为null 或者@Bean方法返回为null
if (beanType != NullBean.class) {
mbd.resolvedTargetType=beanType;
}//执行所有实现了MergedBeanDefinitionPostProcessor接口的类的postProcessMergedBeanDefinition方法
synchronized(mbd.postProcessingLock) {if (!mbd.postProcessed) {try{
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}catch(Throwable ex) {throw newBeanCreationException(mbd.getResourceDescription(), beanName,"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed= true;
}
}//如果允许属性值循环依赖,则将实例其放入一个singletonFactories缓存中,此时该类已经实例化但还未为属性赋值//如果该类依赖的属性值实例化时依赖该类,那么就可以从这个singletonFactories提前拿到还未赋值的属性值实例
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));if(earlySingletonExposure) {if(logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, ()->getEarlyBeanReference(beanName, mbd, bean));
}
Object exposedObject=bean;try{//为实例赋属性值
populateBean(beanName, mbd, instanceWrapper);//执行一些列初始化方法
exposedObject =initializeBean(beanName, exposedObject, mbd);
}catch(Throwable ex) {if (ex instanceof BeanCreationException &&beanName.equals(((BeanCreationException) ex).getBeanName())) {throw(BeanCreationException) ex;
}else{throw newBeanCreationException(
mbd.getResourceDescription(), beanName,"Initialization of bean failed", ex);
}
}//如果允许启用提前暴露缓存//对该结果再做一些特殊处理
if(earlySingletonExposure) {
Object earlySingletonReference= getSingleton(beanName, false);if (earlySingletonReference != null) {if (exposedObject ==bean) {
exposedObject=earlySingletonReference;
}else if (!this.allowRawInjectionDespiteWrapping &&hasDependentBean(beanName)) {
String[] dependentBeans=getDependentBeans(beanName);
Set actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);for(String dependentBean : dependentBeans) {if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}if (!actualDependentBeans.isEmpty()) {throw newBeanCurrentlyInCreationException(beanName,"Bean with name '" + beanName + "' has been injected into other beans [" +StringUtils.collectionToCommaDelimitedString(actualDependentBeans)+
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}//如果bean是一次性的则将其注入一次性使用容器中
try{
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}catch(BeanDefinitionValidationException ex) {throw newBeanCreationException(
mbd.getResourceDescription(), beanName,"Invalid destruction signature", ex);
}returnexposedObject;
}
该方法有几个地方需要注意
实例化bean后检查了该bean是否为null
执行了所有实现了实现了MergedBeanDefinitionPostProcessor接口的类的postProcessMergedBeanDefinition方法
如果出现了属性值循环引用,且允许循环引用,那么会将实例化好但还未赋值的bean放入一个singletonFactories提前暴露容器中来解决属性值循环引用
然后在为属性赋值
然后执行初始化方法。
我们则简要分析下这几个步骤
6.1createBeanInstance创建实例
protectedBeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {//确保beanClass可以被实例化 例如其是否为public
Class> beanClass =resolveBeanClass(mbd, beanName);if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {throw newBeanCreationException(mbd.getResourceDescription(), beanName,"Bean class isn't public, and non-public access not allowed: " +beanClass.getName());
}//查看该类是否有定制的Supplier 如果有直接返回
Supplier> instanceSupplier =mbd.getInstanceSupplier();if (instanceSupplier != null) {returnobtainFromSupplier(instanceSupplier, beanName);
}//查看该类是否为@Bean方法初始化 如果是的话执行方法逻辑
if (mbd.getFactoryMethodName() != null) {returninstantiateUsingFactoryMethod(beanName, mbd, args);
}//Shortcut when re-creating the same bean...
boolean resolved = false;boolean autowireNecessary = false;//如果初始化构造参数为null且能找到构造函数或者FactoryMethod(如果为factoryBean)
if (args == null) {synchronized(mbd.constructorArgumentLock) {if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved= true;//查看其是否有@Autowired的参数
autowireNecessary =mbd.constructorArgumentsResolved;
}
}
}if(resolved) {//如果有@Autowaired参数则执行这个autowireConstructor方法
if(autowireNecessary) {return autowireConstructor(beanName, mbd, null, null);
}//如果没有则执行instantiateBean方法
else{returninstantiateBean(beanName, mbd);
}
}//如果上面没找到有效的构造函数 就从BeanPostProcessor中查找 然后执行返回
Constructor>[] ctors =determineConstructorsFromBeanPostProcessors(beanClass, beanName);if (ctors != null ||mbd.getResolvedAutowireMode()== RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||mbd.hasConstructorArgumentValues()|| !ObjectUtils.isEmpty(args)) {returnautowireConstructor(beanName, mbd, ctors, args);
}//No special handling: simply use no-arg constructor.
returninstantiateBean(beanName, mbd);
}
这儿步骤主要为
1.校验是否能实例化
2.是否有定制的supplier,有则返回
3.是否为@Bean初始化,如果是则执行专门的实例化方法
4.如果传入的构造参数为null,则根据自动注入的参数或者无参的方法来实例化。
5.如果传入的参数不为null 或者需要的参数里有不是自动注入的,那么根据BeanPostProcessor找到合适的构造函数并实例化
这儿具体的对象创建过程由于篇幅就不讲解了,可以根据各个方法进去仔细查看,不过大概能想到的应该就是根据传入的参数反射创建实例,如果是@Bean方法创建的话应该是反射执行方法创建,如果需要代理的话则创建代理对象并返回。
6.2 applyMergedBeanDefinitionPostProcessors
这也是springBean生命周期中的一个重要步骤
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class>beanType, String beanName) {for(BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceofMergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp=(MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
该方法会执行所有的MergedBeanDefinitionPostProcessor 的postProcessMergedBeanDefinition方法。
6.3 处理属性值循环引用addSingletonFactory
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
这儿注意getEarlyBeanReference又会执行所有实现了SmartInstantiationAwareBeanPostProcessor接口的getEarlyBeanReference方法。
此处其实就是利用了一个提前暴露的singletonFactories容器,将实例化但还未赋值的bean放置在其中,当循环引用的bean需要用到这个bean时就可以拿到还未赋值的bean。即可解决属性值循环引用的问题。
protected void addSingletonFactory(String beanName, ObjectFactory>singletonFactory) {
Assert.notNull(singletonFactory,"Singleton factory must not be null");synchronized (this.singletonObjects) {if (!this.singletonObjects.containsKey(beanName)) {this.singletonFactories.put(beanName, singletonFactory); //singletonFactories 提前暴露的Factories容器
this.earlySingletonObjects.remove(beanName);//singletonFactories 提前暴露的bean容器
this.registeredSingletons.add(beanName);//已注册的单例容器
}
}
}
注意这儿有两个容器都涉及到提前引用 ,区别是earlySingletonObjects 放置的实例化的bean 而singletonFactories 放置的是实例化的bean的包装。之所以加个包装是为了获取提前暴露的引用时可以执行SmartInstantiationAwareBeanPostProcessor接口的getEarlyBeanReference方法。
/**Cache of singleton factories: bean name --> ObjectFactory*/
private final Map> singletonFactories = new HashMap<>(16);/**Cache of early singleton objects: bean name --> bean instance*/
private final Map earlySingletonObjects = new HashMap<>(16);
具体的处理循环引用的逻辑文章最后会单独说下,这儿注意get
6.4 为属性赋值
protected voidpopulateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {//判空
if (bw == null) {if(mbd.hasPropertyValues()) {throw newBeanCreationException(
mbd.getResourceDescription(), beanName,"Cannot apply property values to null instance");
}else{//Skip property population phase for null instance.
return;
}
}//检查下是否需要赋值 如果有某个InstantiationAwareBeanPostProcessor返回未false 那么就跳过赋值操作
boolean continueWithPropertyPopulation = true;if (!mbd.isSynthetic() &&hasInstantiationAwareBeanPostProcessors()) {for(BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceofInstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp=(InstantiationAwareBeanPostProcessor) bp;if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation= false;break;
}
}
}
}if (!continueWithPropertyPopulation) {return;
}//获取要赋值的属性值
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);//根据不同的来不同的注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||mbd.getResolvedAutowireMode()==RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs= newMutablePropertyValues(pvs);//by name 例如@Resources
if (mbd.getResolvedAutowireMode() ==RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}//by type 例如@Autowied
if (mbd.getResolvedAutowireMode() ==RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs=newPvs;
}boolean hasInstAwareBpps =hasInstantiationAwareBeanPostProcessors();boolean needsDepCheck = (mbd.getDependencyCheck() !=RootBeanDefinition.DEPENDENCY_CHECK_NONE);//如果有对应的InstantiationAwareBeanPostProcessors则执行下其postProcessPropertyValues方法
if (hasInstAwareBpps ||needsDepCheck) {if (pvs == null) {
pvs=mbd.getPropertyValues();
}
PropertyDescriptor[] filteredPds=filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);if(hasInstAwareBpps) {for(BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceofInstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp=(InstantiationAwareBeanPostProcessor) bp;
pvs=ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);if (pvs == null) {return;
}
}
}
}if(needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}if (pvs != null) {//将找到的属性值赋上
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
该方法检查了下bean是否为空,和该bean是否需要赋值,然后找到了所有的InstantiationAwareBeanPostProcessor执行了下其postProcessPropertyValues (如果需要的话),最后将找到的值赋上。
6.5 初始化方法initializeBean
bean实例化后会执行initializeBean方法。该方法会执行很多bean生命周期相关的方法。
protected Object initializeBean(final String beanName, finalObject bean, @Nullable RootBeanDefinition mbd) {if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction) () ->{
invokeAwareMethods(beanName, bean);return null;
}, getAccessControlContext());
}else{//1.执行所有实现了BeanNameAware的setBeanName方法//2.执行所有实现了BeanClassLoaderAware的setBeanClassLoader方法//3.执行所有实现了BeanFactoryAware的setBeanFactory方法
invokeAwareMethods(beanName, bean);
}
Object wrappedBean=bean;if (mbd == null || !mbd.isSynthetic()) {//执行所有实现了BeanPostProcessor的postProcessBeforeInitialization方法
wrappedBean =applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}try{//如果该类实现了InitializingBean接口,则执行afterPropertiesSet方法
invokeInitMethods(beanName, wrappedBean, mbd);
}catch(Throwable ex) {throw newBeanCreationException(
(mbd!= null ? mbd.getResourceDescription() : null),
beanName,"Invocation of init method failed", ex);
}if (mbd == null || !mbd.isSynthetic()) {//执行所有实现了BeanPostProcessor的postProcessAfterInitialization方法
wrappedBean =applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}returnwrappedBean;
}
该方法会执行很多的spring生命周期的方法,首先会执行一堆的aware前置方法。然后执行BeanPostProcessor的postProcessBeforeInitialization,然后如果该类实现了InitializingBean则执行afterPropertiesSet方法,最后执行BeanPostProcessor的postProcessAfterInitialization方法(该方法可以关注下,spring aop功能正是基于此实现的)。此时创建bean的工作已经基本完成了。
7.回到getSingleton
上面所讲的都是ObjectFactory的回调函数的实现内容,那么调用的时机,和调用的前后逻辑还需要我们了解一下。即本文第4节的getSingtone方法。
public Object getSingleton(String beanName, ObjectFactory>singletonFactory) {
Assert.notNull(beanName,"Bean name must not be null");synchronized (this.singletonObjects) {//看下singletonObject中是否已经有了 如果没有进入创建
Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {//校验一下是否正在创建中,如果正在创建中直接抛异常
if (this.singletonsCurrentlyInDestruction) {throw newBeanCreationNotAllowedException(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加入singletonsCurrentlyInCreation容器
beforeSingletonCreation(beanName);boolean newSingleton = false;boolean recordSuppressedExceptions = (this.suppressedExceptions == null);if(recordSuppressedExceptions) {this.suppressedExceptions = new LinkedHashSet<>();
}try{//执行回调函数的创建逻辑
singletonObject =singletonFactory.getObject();
newSingleton= true;
}catch(IllegalStateException ex) {//Has the singleton object implicitly appeared in the meantime ->//if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {throwex;
}
}catch(BeanCreationException ex) {if(recordSuppressedExceptions) {for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}throwex;
}finally{if(recordSuppressedExceptions) {this.suppressedExceptions = null;
}//从singletonsCurrentlyInCreation容器中移除该bean
afterSingletonCreation(beanName);
}if(newSingleton) {//将该bean添加到singletonObjects容器中 并从提前暴露的容器中移除
addSingleton(beanName, singletonObject);
}
}returnsingletonObject;
}
}
可以看到该类中主要核查防止了重复加载,然后通过回调函数获取我们创建的bean后,将其从提前暴露的容器中移除,然后放入BeanFactory的真正的bean容器中。此时一个bean就算被创建完成已经可以正式使用了。
可以发现其中执行了很多的BeanPostProcessor和aware,这也是spring对bean的扩展性做的极高的一种体现。
到此spring初始化一个bean已经成功了。有关spring的具体加载流程简要图已经在一开始给出,可以对照着查看。而且spring的bean的生命周期除了销毁部分,其他的基本就是上述的内容。
后记
关于spring解决属性循环依赖的问题主要是如下的代码。
protected Object getSingleton(String beanName, booleanallowEarlyReference) {//如果未从singletonObjects获取到就要尝试从提前暴露的容器中拿
Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null &&isSingletonCurrentlyInCreation(beanName)) {synchronized (this.singletonObjects) {//从提前暴露的容器中拿singletonObject
singletonObject = this.earlySingletonObjects.get(beanName);//如果也为空
if (singletonObject == null &&allowEarlyReference) {//那么尝试从提前暴露的包装容器中拿
ObjectFactory> singletonFactory = this.singletonFactories.get(beanName);if (singletonFactory != null) {//如果包装容器不为空,那么就拿到其引用 然后添加到提前暴露容器中 并从提前暴露的包装容器中移除
singletonObject =singletonFactory.getObject();this.earlySingletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);
}
}
}
}returnsingletonObject;
}
可以看到在获取bean时如果没获取到会尝试从提前暴露容器中获取,如果还是获取不到就从提前暴露的包装容器中获取。如果能获取到就将其从包装容器中移除,设置到容器中。