当前位置: 首页 > news >正文

企业网站代码模板陕西百度推广的代理商

企业网站代码模板,陕西百度推广的代理商,在百度上怎么做网站,国内4大现货交易所前言前面几章spring已经把需要的注册的bean的信息已经全部加载到了BeanFactory中了,那么之后要做的事儿当然就是进行实例化了,当然了可能有人会问为何不在加载到bean信息的时候直接进行实例化呢,这不还需要依赖注入嘛,当然是要所有…

前言

前面几章spring已经把需要的注册的bean的信息已经全部加载到了BeanFactory中了,那么之后要做的事儿当然就是进行实例化了,当然了可能有人会问为何不在加载到bean信息的时候直接进行实例化呢,这不还需要依赖注入嘛,当然是要所有的都加载完了才能实例化。ApplicationContext相对于BeanFactory来说,早期的BeanFactory受制于硬件配置,所以在我们需要某个bean的时候才会进行实例化。而ApplicationContext则会在一开始就将所有的注册的Bean(标记懒加载的,或者非单例加载除外)全部进行实例化。本文则主要介绍spring如何实例化bean,并且Bean的生命周期也会穿插其中。

这儿先放一张加载的大致流程图

   referrerpolicy=

从图中可以看到加正式加载的过程并不多,实例化->放入提前暴露容器->赋值完成后其实就算完成实例化了,但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时如果没获取到会尝试从提前暴露容器中获取,如果还是获取不到就从提前暴露的包装容器中获取。如果能获取到就将其从包装容器中移除,设置到容器中。

http://www.lbrq.cn/news/2768905.html

相关文章:

  • wordpress php学习志鸿优化设计
  • 海南州商城网站建设网页设计排版布局技巧
  • 做网站的术语网络营销方案有哪些
  • 游乐园网站建设长沙互联网推广公司
  • 哪个网站做美食视频软件网站如何注册
  • 博客建站模板全球搜
  • 需求登记网站怎么做百度店铺
  • 烟台网站定制排名国外推广网站
  • 做新闻网站服务器选购软文宣传
  • 建立专业的官方网站手机端搜索引擎排名
  • 深圳免费网站建设怎么做网络营销推广啊
  • dede网站百度广告联盟网站
  • 苏中建设官方网站seo大牛
  • 全球最大的设计网站刷seo关键词排名软件
  • 做简报的网站百度网址查询
  • 沉默是金seo推广沧州公司电话
  • 海南省建设设厅官方网站网站优化外包多少钱
  • 做网站必须在工信部备案吗附近的成人电脑培训班
  • 怎样把域名和做的网站连接不上白杨seo教程
  • 搭建个网站深圳网站seo地址
  • 国际会议网站建设北京疫情最新消息情况
  • 做网站快速排名百度灰色关键词代发
  • 陕西省建设招投标网站前端培训班一般多少钱
  • 现在做跨境电商还能赚钱吗一键关键词优化
  • 温州做外贸网站设计苏州网站维护
  • 手机网站制作视频教程企业培训课程开发
  • 如何做好网站建设免费建站免费推广的网站
  • 建站工具 营销成都网站seo外包
  • 江门网站优化快速排名爱站关键词挖掘查询工具
  • 郑州做网站优化运营商武汉企业网站推广
  • Ansible 中的文件包含与导入机制
  • 项目管理.管理理念学习
  • Linux下的软件编程——IPC机制
  • Git-2025-0818
  • 44.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--扩展功能--集成网关--网关集成认证(三)
  • 智能制造——解读37页 案例分享灯塔工厂解决方案【附全文阅读】