spring 创建bean的过程以及循环依赖的解决方案
-
准备Bean容器 prepareApplicationContext() (重要!!)
-
设置环境 environment到context容器中,添加各种listener等
-
refreshContext(重要)
在这一步中,刷新整个context,此操作将注册所有bean到BeanFactory中,启动spring boot 中的webserver等
详细的refresh操作如下
@Override public void refresh() throws BeansException, IllegalStateException { // 上锁 synchronized (this.startupShutdownMonitor) { // 准备工作,记录下容器的启动时间、标记“已启动”状态、处理配置文件中的占位符 prepareRefresh(); // 这步比较关键,这步完成后,配置文件就会解析成一个个 Bean 定义,注册到 BeanFactory 中, // 当然,这里说的 Bean 还没有初始化,只是配置信息都提取出来了, // 注册也只是将这些信息都保存到了注册中心(说到底核心是一个 beanName-> beanDefinition 的 map) ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean // 这块待会会展开说 prepareBeanFactory(beanFactory); try { // 【这里需要知道 BeanFactoryPostProcessor 这个知识点,Bean 如果实现了此接口, // 那么在容器初始化以后,Spring 会负责调用里面的 postProcessBeanFactory 方法。】 // 这里是提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化 // 具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事 postProcessBeanFactory(beanFactory); // 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法 invokeBeanFactoryPostProcessors(beanFactory); // 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别 // 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization // 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化 registerBeanPostProcessors(beanFactory); // 初始化当前 ApplicationContext 的 MessageSource,国际化不是重点,不展开 initMessageSource(); // 初始化当前 ApplicationContext 的事件广播器,这里也不展开了 initApplicationEventMulticaster(); // 从方法名就可以知道,典型的模板方法(钩子方法), // 具体的子类可以在这里初始化一些特殊的 Bean(在初始化 singleton beans 之前) onRefresh(); // 注册事件监听器,监听器需要实现 ApplicationListener 接口。这也不是我们的重点,过 registerListeners(); // 重点,重点,重点 // 初始化所有的 singleton beans //(lazy-init 的除外) finishBeanFactoryInitialization(beanFactory); // 最后,广播事件,ApplicationContext 初始化完成 finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. // 销毁已经初始化的 singleton 的 Beans,以免有些 bean 会一直占用资源 destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }
spring中要求context的refresh操作必须是线程安全的,所以使用了startupShutdownMonitor为代码块上锁,同时使用到该锁的还有close()方法,让refresh和close不能同时进行
-
spring bean 存储和获取过程
我们知道,spring在启动过程中会有依赖注入这一特性,即标记了@Autowired的成员变量会被spring进行递归注册bean,下面介绍他们的实现,首先打出递归调用栈
这张图表明了spring在获取一个bean的时候,如果没有,会先去创建一个bean,在创建的过程中会去创建所有被引用的且未被创建的bean,最终又会调用getBean方法进行递归,下面会逐个介绍所有方法
spring获取过程 doGetBean()
spring bean的获取主要是通过BeanFactory做到的,在获取bean的过程中,spring实现了依赖注入这样的核心功能。一下为源码
源代码在org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean中
/**
* Return an instance, which may be shared or independent, of the specified bean.
* @param name the name of the bean to retrieve
* @param requiredType the required type of the bean to retrieve
* @param args arguments to use when creating a bean instance using explicit arguments
* (only applied when creating a new instance as opposed to retrieving an existing one)
* @param typeCheckOnly whether the instance is obtained for a type check,
* not for actual use
* @return an instance of the bean
* @throws BeansException if the bean could not be created
*/
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
//拿到bean的名称
final String beanName = transformedBeanName(name);
Object bean;
//检查是否是singleton 的作用域,总所周知,spring拥有singleton、prototype、session等作用域,以下方法是查找单例singleton作用域的
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 {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
//创建过了此 beanName 的 prototype 类型的 bean,那么抛异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
// 检查下这个BeanDefinition是否存在
BeanFactory parentBeanFactory = getParentBeanFactory();
// 如果当前没有且parent不为空,就去parent里去找
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) {
markBeanAsCreated(beanName);
}
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
//找到depends-on类型的引用 depends-on 的循环引用要求明确使用@DependsOn注解 表明当实例化一个bean时,spring保证该Bean所依赖的其他bean已经初始化
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
/// 这里指的是通过 depends-on 定义造成的循环依赖,注意和类成员式的循环引用区分开
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
//如果是singleton的,就创建singleton实例
if (mbd.isSingleton()) {
//获取singleton源码,
sharedInstance = getSingleton(beanName, () -> {
try {
//创建bean的详情,创建bean的过程中会为为所有标记了被spring托管的类的field进行递归作doGetBean()的操作
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);
}
//如果是prototype的,创建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);
}
//如果不是singleton或者prototype的话,就委托给相应的实现类来处理
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 {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(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);
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
// 最后再检查一下类型
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.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
实例化bean的过程 doCreateBean
实例化bean的步骤主要有三个
createBeanInstance 实例化 -----> populateBean填充属性 --------> InitializeBean 初始化
在doGetBean()方法的调用过程中,在singleton作用域下spring会调用createBean()去实例化一个bean() createBean会组装好数据后,最终调用doCreateBean()方法实例化bean,具体代码如下
/**
* Actually create the specified bean. Pre-creation processing has already happened
* at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
* <p>Differentiates between default bean instantiation, use of a
* factory method, and autowiring a constructor.
* @param beanName the name of the bean
* @param mbd the merged bean definition for the bean
* @param args explicit arguments to use for constructor or factory method invocation
* @return a new instance of the bean
* @throws BeanCreationException if the bean could not be created
* @see #instantiateBean
* @see #instantiateUsingFactoryMethod
* @see #autowireConstructor
*/
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
// BeanWrapper为Bean的包装类,持有新创建的bean的引用
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
//如果是singleton作用域的话,则把想用name的bean从缓存中删掉
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//真正实例化bean在下面的方法完成,下文还有介绍
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final 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 {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
// 这里是为了解决循环依赖的,先把初步实例化的Bean实例的引用缓存起来,暴露出去
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));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 填充新添加bean的属性,循环引用这里会调用
populateBean(beanName, mbd, instanceWrapper);
// 处理 InitializingBean 接口、BeanPostProcessor 接口等
// 这里就是处理 bean 初始化完成后的各种回调,调用顺序 调用BeanPostProcessor.postProcessBeforeInitialization() -> InitializingBean.afterPropertiesSet() ->
// 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);
}
}
//如果该beanName对象已经注册单例模式,则从单例中获取,并判断获取到的bean实例(B)与BeanWrapper中的bean实例(A)是同一个实例,如果是,则返回A或者B,如果不是,则递归找出它的依赖bean。
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
// earlySingletonReference只有在检测到有循环依赖的情况下才会不为空
if (earlySingletonReference != null) {
if (exposedObject == 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,
"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.");
}
}
}
}
// Register bean as disposable.
// 编辑注册的bean为可使用状态
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
spring解决循环引用问题
循环引用问题在spring中非常常见,即假设spring中A对象中含有标记了@Autowired的B对象的成员变量,B中同样含有标记了@Autowired的A对象的成员变量,称为循环引用。
循环引用分析
上文提到,spring 单例对象的创建主要分为三步
createBeanInstance 实例化 -----> populateBean填充属性 --------> InitializeBean 初始化
对于单例来说,在Spring容器整个生命周期内,有且只有一个对象,所以很容易想到这个对象应该存在Cache中,Spring为了解决单例的循环依赖问题,使用了三级缓存。
代码在org.springframework.beans.factory.support.DefaultSingletonBeanRegistry中
/** Cache of singleton objects: bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);
/** Cache of singleton factories: bean name --> ObjectFactory */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);
/** Cache of early singleton objects: bean name --> bean instance */
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
/** Names of beans that are currently in creation */
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<>(16)); //spring会将正在创建的bean的name放入该set
这三级缓存分别指:
singletonFactories : 单例对象工厂的cache
earlySingletonObjects :提前暴光的单例对象的Cache
singletonObjects:单例对象的cache
所以,在获取singleton bean的方法getSingleton源码如下
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName); //从一级缓存中直接获取
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { //如果缓存中没有并且bean正在被创建中
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName); //从二级缓存earlySingletonObjects中获取,earlySingletonObjects表示可以提前暴露给context的bean,
//表名只进行了第一步操作,没有执行后续填充属性和初始化
if (singletonObject == null && allowEarlyReference) { //如果还是没有并且允许从factory中获取对象的话
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);//从factotyMap中获取factory
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject(); //从factory中获取对象
this.earlySingletonObjects.put(beanName, singletonObject); //加入到二级缓存中
this.singletonFactories.remove(beanName);//从一级缓存中删除
}
}
}
}
return singletonObject;
}
在依赖注入创建bean的过程中,spring通过把实例化好的bean以缓存的方式提前暴露给全局context的形式 在上面的代码中其实已经看到,这里再贴一次。
代码在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean中
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
// 这里是为了解决循环依赖的,先把初步实例化的Bean实例的引用缓存起来,暴露出去
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName)); //如果对象是singleton 并且允许循环引用并且bean是处于正在被创建状态,就执行下面的方法
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); //就EarlyBean引用添加到factory中
}
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) { //上锁
if (!this.singletonObjects.containsKey(beanName)) { //如果实例好的singleton bean中没有
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName); //将bean从提前暴光的单例对象中删除
this.registeredSingletons.add(beanName);
}
}
}
这段代码发生在createBeanInstance之后,也就是说单例对象此时已经被创建出来(调用了构造器)。这个对象已经被生产出来了,虽然还不完美(还没有进行初始化的第二步和第三步),但是已经能被人认出来了(根据对象引用能定位到堆中的对象),所以Spring此时将这个对象提前曝光出来让大家认识,让大家使用。
这样做有什么好处呢?让我们来分析一下“A的某个field或者setter依赖了B的实例对象,同时B的某个field或者setter依赖了A的实例对象”这种循环依赖的情况。A首先完成了初始化的第一步,并且将自己提前曝光到singletonFactories中,此时进行初始化的第二步,发现自己依赖对象B,此时就尝试去get(B),发现B还没有被create,所以走create流程,B在初始化第一步的时候发现自己依赖了对象A,于是尝试get(A),尝试一级缓存singletonObjects(肯定没有,因为A还没初始化完全),尝试二级缓存earlySingletonObjects(也没有),尝试三级缓存singletonFactories,由于A通过ObjectFactory将自己提前曝光了,所以B能够通过ObjectFactory.getObject拿到A对象(虽然A还没有初始化完全,但是总比没有好呀),B拿到A对象后顺利完成了初始化阶段1、2、3,完全初始化之后将自己放入到一级缓存singletonObjects中。此时返回A中,A此时能拿到B的对象顺利完成自己的初始化阶段2、3,最终A也完成了初始化,进去了一级缓存singletonObjects中,而且更加幸运的是,由于B拿到了A的对象引用,所以B现在hold住的A对象完成了初始化。
真正实例化bean的地方 createBeanInstance()
在上面的doCreateBean的方法中,调用了该方法来真正实例化bean
/**
* Create a new instance for the specified bean, using an appropriate instantiation strategy:
* factory method, constructor autowiring, or simple instantiation.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @param args explicit arguments to use for constructor or factory method invocation
* @return a BeanWrapper for the new instance
* @see #obtainFromSupplier
* @see #instantiateUsingFactoryMethod
* @see #autowireConstructor
* @see #instantiateBean
*/
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
//解析bean的class
Class<?> beanClass = resolveBeanClass(mbd, beanName);
//检查bean的权限
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 如果工厂方法不为空,则是用工厂方法初始化
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
//如果有解析过的构造方法或者工厂方法,则标志resolve为true
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
//构造方法自动注入,这里面又是依赖注入,最终还是会递归到doGetBean
return autowireConstructor(beanName, mbd, null, null);
}
else {
//否则直接instance
return instantiateBean(beanName, mbd);
}
}
// Candidate constructors for autowiring?
//构造构造函数
// 判断是否采用有参构造函数
// 构造器自动装配
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
//构造方法自动注入
return autowireConstructor(beanName, mbd, ctors, args);
}
// 否则直接instance
return instantiateBean(beanName, mbd);
}
创建bean后的填充对象 populateBean()
因为是填充bean对象的所有field,即实例化bean的所有成员变量。所以采用@Autowired注解的引用会在这里进行依赖注入。下面来看源码
/**
* Populate the bean instance in the given BeanWrapper with the property values
* from the bean definition.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @param bw the BeanWrapper with bean instance
*/
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
boolean continueWithPropertyPopulation = true;
// 这里看注解是一个扩展点
// InstantiationAwareBeanPostProcessor 的实现类可以在这里对 bean 进行状态修改
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
//如果模式为通过bean名称装配或者通过type装配,则进入
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
//通过beanName装配
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
//通过type装配()
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// InstantiationAwareBeanPostProcessor.postProcessPropertyValues方法
// 代表能对属性值进行修改的能力
// 其中一个很有用实现类提一下,AutowiredAnnotationBeanPostProcessor
// 对采用@Autowired和@Value设值的就是这个BeanPostProcessor干的。
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);
}
}
采用@Autowired 方式注入的具体实现
依赖注入最开始在doGetBean()方法中调用registerDependentBean,
spring 依赖注入 @Autowired 通过 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues
具体注入代码
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
if (this.cached) {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
else {
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
//拿到需要注入的对象 即field,这里,最终会重新调到doGetBean方法实现依赖注入
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {
if (!this.cached) {
if (value != null || this.required) {
this.cachedFieldValue = desc;
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
this.cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
else {
this.cachedFieldValue = null;
}
this.cached = true;
}
}
}
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
}