首页 > 其他分享 >spring启动流程 (2) Bean实例化流程

spring启动流程 (2) Bean实例化流程

时间:2023-07-02 15:26:24浏览次数:48  
标签:mbd spring 流程 beanName Bean bean ex null

本文通过阅读Spring源码,分析Bean实例化流程。

Bean实例化入口

上一篇文章已经介绍,Bean实例化入口在AbstractApplicationContext类的finishBeanFactoryInitialization方法:

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
	// Initialize conversion service for this context.
	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.
	if (!beanFactory.hasEmbeddedValueResolver()) {
		beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
	}

	// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
	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.
	beanFactory.freezeConfiguration();

	// Instantiate all remaining (non-lazy-init) singletons.
	// 实例化Bean
	beanFactory.preInstantiateSingletons();
}

Bean实例化流程

public void preInstantiateSingletons() throws BeansException {

	// 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...
	for (String beanName : beanNames) {
		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
		// 判断非抽象,单例且非懒加载
		if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
			// 判断FactoryBean
			if (isFactoryBean(beanName)) {
				// 使用"&beanName"格式作为beanName去创建Bean实例
				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 {
				// 普通的Bean
				getBean(beanName);
			}
		}
	}

	// Trigger post-initialization callback for all applicable beans...
	// 此分支暂时不做分析
	for (String beanName : beanNames) {
		Object singletonInstance = getSingleton(beanName);
		if (singletonInstance instanceof SmartInitializingSingleton) {
			SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
			if (System.getSecurityManager() != null) {
				AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
					smartSingleton.afterSingletonsInstantiated();
					return null;
				}, getAccessControlContext());
			} else {
				smartSingleton.afterSingletonsInstantiated();
			}
		}
	}
}

getBean(beanName)方法

public Object getBean(String name) throws BeansException {
	return doGetBean(name, null, null, false);
}

protected <T> T doGetBean(
		String name, Class<T> requiredType, Object[] args, boolean typeCheckOnly)
		throws BeansException {

	// 去除name的&前缀
	String beanName = transformedBeanName(name);
	Object bean;

	// 依次从singletonObjects, earlySingletonObjects, singletonFactories获取单例Bean
	// 如果找到了就不需要创建了
	Object sharedInstance = getSingleton(beanName);
	if (sharedInstance != null && args == null) {
		// Get the object for the given bean instance,
		// either the bean instance itself or its created object in case of a FactoryBean.
		// name参数是调用getBean方法时传递的原始BeanName,可能前缀&符用于获取FactoryBean实例
		// beanName参数是去除&符前缀后的BeanName
		bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
	} else {
		// Fail if we're already creating this bean instance:
		// We're assumably within a circular reference.
		if (isPrototypeCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}

		// 如果当前BeanFactory没有指定Bean则从父级BeanFactory获取Bean实例
		BeanFactory parentBeanFactory = getParentBeanFactory();
		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 if (requiredType != null) {
				// No args -> delegate to standard getBean method.
				return parentBeanFactory.getBean(nameToLookup, requiredType);
			} else {
				return (T) parentBeanFactory.getBean(nameToLookup);
			}
		}

		// whether the instance is obtained for a type check, not for actual use
		if (!typeCheckOnly) {
			markBeanAsCreated(beanName);
		}

		try {
			RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
			checkMergedBeanDefinition(mbd, beanName, args);

			// 创建DependsOn的Bean
			String[] dependsOn = mbd.getDependsOn();
			if (dependsOn != null) {
				for (String dep : dependsOn) {
					// 判断循环依赖
					if (isDependent(beanName, dep)) {
						throw new BeanCreationException(
                            mbd.getResourceDescription(), beanName, "循环依赖");
					}
					registerDependentBean(dep, beanName);
					try {
						getBean(dep);
					} catch (NoSuchBeanDefinitionException ex) {
						throw new BeanCreationException(
                            mbd.getResourceDescription(), beanName, "依赖的Bean不存在", ex);
					}
				}
			}

			// 此分支获取单例Bean
			if (mbd.isSingleton()) {
				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;
					}
				});
				bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
			} else if (mbd.isPrototype()) {
				// 此分支获取Prototype类型的Bean
				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");
				}
				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 BeanCreationException(
                        beanName, "Scope is not active for the current thread", ex);
				}
			}
		} catch (BeansException ex) {
			cleanupAfterBeanCreationFailure(beanName);
			throw ex;
		}
	}

	// 类型转换
	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) {
			throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
		}
	}
	return (T) bean;
}

创建/获取单例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;
	}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);

getSingleton

返回指定beanName的(原始)单例对象,如果没有则创建一个新对象:

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
	synchronized (this.singletonObjects) {
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null) {
			// 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 (this.singletonsCurrentlyInDestruction) {
				throw new BeanCreationNotAllowedException(beanName, "");
			}
			beforeSingletonCreation(beanName);
			boolean newSingleton = false;
			boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
			if (recordSuppressedExceptions) {
				this.suppressedExceptions = new LinkedHashSet<>();
			}
			try {
				// 此处需要返回去看createBean(beanName, mbd, args)的代码
				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) {
					throw ex;
				}
			} catch (BeanCreationException ex) {
				if (recordSuppressedExceptions) {
					for (Exception suppressedException : this.suppressedExceptions) {
						ex.addRelatedCause(suppressedException);
					}
				}
				throw ex;
			} finally {
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = null;
				}
				afterSingletonCreation(beanName);
			}
			if (newSingleton) {
				// 将创建的单例放入单例池
				addSingleton(beanName, singletonObject);
			}
		}
		return singletonObject;
	}
}

protected void addSingleton(String beanName, Object singletonObject) {
	synchronized (this.singletonObjects) {
		this.singletonObjects.put(beanName, singletonObject);
		this.singletonFactories.remove(beanName);
		this.earlySingletonObjects.remove(beanName);
		this.registeredSingletons.add(beanName);
	}
}

createBean

创建Bean实例、填充属性、调用后置处理器等:

protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args)
		throws BeanCreationException {

	RootBeanDefinition mbdToUse = mbd;

	// Make sure bean class is actually resolved at this point, and
	// clone the bean definition in case of a dynamically resolved Class
	// which cannot be stored in the shared merged bean definition.
	Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
	if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
		mbdToUse = new RootBeanDefinition(mbd);
		mbdToUse.setBeanClass(resolvedClass);
	}

	// Prepare method overrides.
	try {
		mbdToUse.prepareMethodOverrides();
	} catch (BeanDefinitionValidationException ex) {
		throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
				beanName, "Validation of method overrides failed", ex);
	}

	try {
		// 调用BeanPostProcessor处理器
		// 调用postProcessBeforeInstantiation方法
		Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
		// 如果后置处理器返回了Bean实例则直接返回
		if (bean != null) {
			return bean;
		}
	} catch (Throwable ex) {
		throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
				"BeanPostProcessor before instantiation of bean failed", ex);
	}

	try {
		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
		return beanInstance;
	} catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
		// A previously detected exception with proper bean creation context already,
		// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
		throw ex;
	} catch (Throwable ex) {
		throw new BeanCreationException(
				mbdToUse.getResourceDescription(), beanName, 
				"Unexpected exception during bean creation", ex);
	}
}

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
		throws BeanCreationException {

	// Instantiate the bean.
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) {
		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
	}
	if (instanceWrapper == null) {
		// 创建实例,使用BeanWrapper包装
		// 构造方法的@Autowired也在这里面实现
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	}
	Object bean = instanceWrapper.getWrappedInstance();
	Class<?> beanType = instanceWrapper.getWrappedClass();
	if (beanType != NullBean.class) {
		mbd.resolvedTargetType = beanType;
	}

	// Allow post-processors to modify the merged bean definition.
	synchronized (mbd.postProcessingLock) {
		if (!mbd.postProcessed) {
			try {
				// 调用MergedBeanDefinitionPostProcessor处理器
				applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
			} catch (Throwable ex) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Post-processing of merged bean definition failed", ex);
			}
			mbd.postProcessed = true;
		}
	}

	// 这里使用三级缓存封装了一段代码,解决循环依赖问题
	// 这段代码会执行SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference方法
	// 依赖这个Bean的其他Bean在填充属性时,调用getSingleton时会执行getEarlyBeanReference方法
	// 此时可以对这个Bean实例做一些事情,比如创建AOP代理
	// 之后会将修改之后的对象放入到二级缓存
	boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
			isSingletonCurrentlyInCreation(beanName));
	if (earlySingletonExposure) {
		addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
	}

	// Initialize the bean instance.
	Object exposedObject = bean;
	try {
		// Populate the bean instance in the given BeanWrapper 
		// with the property values from the bean definition.
		// 1. 调用InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation方法
		// 2. 依赖注入
		populateBean(beanName, mbd, instanceWrapper);
		// Initialize the given bean instance, applying factory 
		// callbacks as well as init methods and bean post processors.
		// 1. invokeAwareMethods
		// 2. 调用BeanPostProcessor的postProcessBeforeInitialization
		// 3. InitializingBean的afterPropertiesSet和initMethod
		// 4. 调用BeanPostProcessor的postProcessAfterInitialization
		exposedObject = initializeBean(beanName, exposedObject, mbd);
	} catch (Throwable ex) {
		if (ex instanceof BeanCreationException && 
            beanName.equals(((BeanCreationException) ex).getBeanName())) {
			throw (BeanCreationException) ex;
		} else {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
		}
	}

	if (earlySingletonExposure) {
		// 获取提前暴露的Bean实例
		Object earlySingletonReference = getSingleton(beanName, false);
		if (earlySingletonReference != null) {
			if (exposedObject == bean) {
				// 使用提前暴露的Bean替换当前Bean
				exposedObject = earlySingletonReference;
			} else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
				String[] dependentBeans = getDependentBeans(beanName);
				Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
				for (String dependentBean : dependentBeans) {
					if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
						actualDependentBeans.add(dependentBean);
					}
				}
				if (!actualDependentBeans.isEmpty()) {
					throw new BeanCurrentlyInCreationException(beanName, "");
				}
			}
		}
	}

	// Register bean as disposable.
	try {
		registerDisposableBeanIfNecessary(beanName, bean, mbd);
	} catch (BeanDefinitionValidationException ex) {
		throw new BeanCreationException(
				mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
	}

	return exposedObject;
}

创建Prototype类型的Bean

// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
	// 把beanName注册到ThreadLocal prototypesCurrentlyInCreation中
	beforePrototypeCreation(beanName);
	// 这里的逻辑与singleton一样了
	prototypeInstance = createBean(beanName, mbd, args);
} finally {
	// 把beanName从ThreadLocal prototypesCurrentlyInCreation清除
	afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);

标签:mbd,spring,流程,beanName,Bean,bean,ex,null
From: https://www.cnblogs.com/xugf/p/17520814.html

相关文章

  • SpringBoot 插件化开发模式
    1、Java常用插件实现方案1.2、serviceloader方式serviceloader是java提供的spi模式的实现。按照接口开发实现类,而后配置,java通过ServiceLoader来实现统一接口不同实现的依次调用。而java中最经典的serviceloader的使用就是Java的spi机制。1.2.1、javaspiSPI全称ServiceProv......
  • Common BeanUtils组件的使用(源码)
    CommonBeanUtils组件方便了对JavaBean的使用。其中的一些类方法,使我们使用JavaBean得到了便利。 使用CommonBeanUtils组件需要三个Jar包,分别是commons-beanutils-1.8.0-BETA.jarcommons-logging-1.1.1.jarcommons-logging-api-1.1.1.jar 可从官网下载,不过为了方便,我把三个包传......
  • spring中的controller种类
     http://xiaohu0901.iteye.com/blog/608906一、springmvc中常见controller1、org.springframework.web.servlet.mvc.ParameterizableViewController  这个controller主要用在不需要后台业务逻辑处理的地方,直接在配置文件中指定视图渲染的路径,如下:  <beanid="paramCont......
  • spring 监听器 IntrospectorCleanupListener简介
     spring中的提供了一个名为org.springframework.web.util.IntrospectorCleanupListener的监听器。它主要负责处理由JavaBeans Introspector的使用而引起的缓冲泄露。spring中对它的描述如下: 它是一个在web应用关闭的时候,清除JavaBeansIntrospector的监听器.在web.xml中......
  • Spring factory load
    if(!classpathPrefix.endsWith("/"))classpathPrefix=classpathPrefix+"/";GenericApplicationContextappContext=null;if(useCache)appContext=getCachedContext(classpathPrefix,batchName);if(appContext!=null){......
  • 在spring 的jdbc sql中使用in 语句
    1.<propertyname="sqlSelectPricesForHoldAssetByDate"><value>selectA.ASSETPRICEID,A.ASSETID,A.SOURCE,A.ASOFDATE,A.CURRENCY,A.BID,A.ASKfromassetpriceAINNERJOINloanfacilitylfONA.assetid=lf.assetidwh......
  • 使用Spring的NamedParameterJdbcTemplate完成DAO操作
    NamedParameterJdbcTemplate内部包含了一个JdbcTemplate,所以JdbcTemplate能做的事情NamedParameterJdbcTemplate都能干,NamedParameterJdbcTemplate相对于JdbcTemplate主要增加了参数可以命名的功能。publicObjectqueryForObject(Stringsql,MapparamMap,RowMapperrowMapper)......
  • ResponseBean返回参数实体类
    //T是泛型标签,代表可以给ResponseBean类型对象传入任何类型的属性值publicclassResponseBean<T>{//要封装的数据privateTdata;//数据状态码,用于程序逻辑判断privateIntegercode;//数据状态信息,用于显示在前端视图上privateStrin......
  • (六)Spring源码解析:Spring AOP源码解析
    〇、AOP概念Aspect:切面给业务方法增加到功能,切面泛指交叉业务逻辑。上例中的事务处理、日志处理就可以理解为切面。常用的切面是通知(Advice)。实际就是对主业务逻辑的一种增强。Pointcut:切入点切入点指声明的一个或多个连接点的集合,通过切入点指定一组方法。被标记为final......
  • 部署springboot项目到linux服务器
    1.使用Xshell连接服务器xshell免费版地址:家庭/学校免费-NetSarangWebsite(xshell.com)2.安装java运行环境sudoaptinstallopenjdk-8-jdk3.使用xftp上传后端jar包文件xftp免费版地址:家庭/学校免费-NetSarangWebsite(xshell.com)4.在xshell中使用命令......