Bean生命周期流程--下
Posted 热爱编程的大忽悠
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Bean生命周期流程--下相关的知识,希望对你有一定的参考价值。
Bean生命周期流程--下
引言
生命周期流程-上我们还剩下两个重要的方法未讲解,分别是: populateBean和initializeBean,本文我们一起来看一下。
AbstractAutowireCapableBeanFactory#populateBean实现依赖注入
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw)
...
boolean continueWithPropertyPopulation = true;
//给InstantiationAwareBeanPostProcessors最后一次机会在属性注入前修改Bean的属性值
//具体通过调用postProcessAfterInstantiation方法,如果调用返回false,表示不必继续进行依赖注入,直接返回
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors())
for (BeanPostProcessor bp : getBeanPostProcessors())
if (bp instanceof InstantiationAwareBeanPostProcessor)
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//postProcessAfterInstantiation 这个方法返回true,后面的处理器才会继续执行,单反返回false,后面的就不会再执行了
//并且continueWithPropertyPopulation 打上标记表示false,也就是说后面的属性复制就不会再执行了
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName))
continueWithPropertyPopulation = false;
break;
// 处理器若告知说不用继续赋值了,那就以处理器的结果为准即可
if (!continueWithPropertyPopulation)
return;
//pvs是一个MutablePropertyValues实例,里面实现了PropertyValues接口,提供属性的读写操作实现,同时可以通过调用构造函数实现深拷贝
//本例中,我们的helloServiceImpl的Bean定义里,pvs为null
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
//根据Bean配置的依赖注入方式完成注入,默认是0,即不走以下逻辑,所有的依赖注入都需要在xml(或者@Bean中)文件中有显式的配置
//如果设置了相关的依赖装配方式,会遍历Bean中的属性,根据类型或名称来完成相应注入,无需额外配置
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE)
// 深拷贝当前已有的配置
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
// 根据名称进行注入(见下)
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME)
autowireByName(beanName, mbd, bw, newPvs);
// Add property values based on autowire by type if applicable.
// 根据类型进行注入(见下)
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE)
autowireByType(beanName, mbd, bw, newPvs);
//结合注入后的配置,覆盖当前配置
pvs = newPvs;
// 显然hasInstAwareBpps=true,
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
//是否进行依赖检查 默认值就是None 所以此处返回false,表示不需要依赖检查(关于依赖检查的4种模式,建议使用@Required来显示控制)
//@Required注解作用于BeanSetter方法上,用于检查一个Bean的属性的值在配置期间是否被赋予或设置(populated)
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck)
if (pvs == null)
pvs = mbd.getPropertyValues();
// 过滤出所有需要进行依赖检查的属性编辑器
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
// 在这个节点上:调用了InstantiationAwareBeanPostProcessor#postProcessPropertyValues方法,
// 若返回null,整个populateBean方法就结束了=============
if (hasInstAwareBpps)
for (BeanPostProcessor bp : getBeanPostProcessors())
if (bp instanceof InstantiationAwareBeanPostProcessor)
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 关于postProcessPropertyValues的实现,有几个处理器是非常关键的:
// 比如AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor等等,且看下面的分解
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
// 若返回null,Spring表示你已经属性值都设置好了,那他也不再管了
if (pvs == null)
return;
// 显然,现在大多数情况下,都不会在check这个了
if (needsDepCheck)
checkDependencies(beanName, mbd, filteredPds, pvs);
// 将pvs上所有的属性填充到BeanWrapper对应的Bean实例中
// 注意:这一步完成结束后为止。我们的HelloServiceImpl这个Bean依赖的parent,还只是RuntimeBeanReference类型,还并不是真实的Parent这个Bean
//在Spring的解析段,其它容器中是没有依赖的Bean的实例的,因此这个被依赖的Bean需要表示成RuntimeBeanReferenc对象,并将它放到BeanDefinition的MutablePropertyValues中。
if (pvs != null)
applyPropertyValues(beanName, mbd, bw, pvs);
先看看autowireByName和autowireByType这两步是怎么实现的:
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs)
//根据bw的PropertyDescriptors,遍历出所有可写的(即set方法存在),存在于BeanDefinition里的PropertyValues,且不是简单属性的属性名
//简单属性的判定参照下面方法,主要涵盖基本类型及其包装类,Number,Date等=============
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames)
// 显然,只有容器里存在的,才能根据这个名称注册进去。
//注意,这里存在,有点意思:含有Bean,或者Bean定义等等都算
/** @Override
public boolean containsBean(String name)
String beanName = transformedBeanName(name);
// 首先工厂里必须有单例Bean,或者bean定义
// 然后还必须不是BeanFactory(不是&打头),或者是FactoryBean 就算是包含这个Bean的
if (containsSingleton(beanName) || containsBeanDefinition(beanName))
return (!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(name));
// Not found -> check parent. 看看父容器里有木有
BeanFactory parentBeanFactory = getParentBeanFactory();
return (parentBeanFactory != null && parentBeanFactory.containsBean(originalBeanName(name)));
*/
// 再说明一下containsLocalBean这个方法,和containsBean的区别在于它只在自己的容器里找,不去父容器里找,其余的一样
if (containsBean(propertyName))
// 注意:此处找到依赖了,调用了getBean(),所以即使你现在仅仅只是Bean定义,那么会被创建实例对象
Object bean = getBean(propertyName);
pvs.add(propertyName, bean);
// 注册依赖关系
// 此处需要知道的是:Spring中使用dependentBeanMap和dependenciesForBeanMap来管理这些Bean的依赖关系:
//Map<String, Set<String>> dependentBeanMap:存放着当前Bean被引用的Bean的集合
//Map<String, Set<String>> dependenciesForBeanMap:存放的则是当前Bean所依赖的Bean的集合
//依赖注入的具体实现是在BeanWrapperImpl类中的setPropertyValue方法里=======================
registerDependentBean(propertyName, beanName);
if (logger.isDebugEnabled())
logger.debug("Added autowiring by name from bean name '" + beanName +
"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
else
if (logger.isTraceEnabled())
logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
"' by name: no matching bean found");
protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs)
// 类型转换器,如果没有指定,就用BeanWrapper这个转换器
TypeConverter converter = getCustomTypeConverter();
if (converter == null)
converter = bw;
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames)
try
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
// Don't try autowiring by type for type Object: never makes sense,
// even if it technically is a unsatisfied, non-simple property.
//如果是Object类型不进行装配==============
if (Object.class != pd.getPropertyType())
// 获取相关的写方法参数
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// Do not allow eager init for type matching in case of a prioritized post-processor.
// 看看实例是否实现了PriorityOrdered接口,若没有实现 就稍后点加载吧-----
boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
// 这里会根据传入desc里的入参类型,作为依赖装配的类型
// 再根据这个类型在BeanFacoty中查找所有类或其父类相同的BeanName
// 最后根据BeanName获取或初始化相应的类,然后将所有满足条件的BeanName填充到autowiredBeanNames中。
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null)
pvs.add(propertyName, autowiredArgument);
// 需要注入的依赖都拿到后,就开始注册这些依赖吧
for (String autowiredBeanName : autowiredBeanNames)
// 一样的 这里注册这些依赖
registerDependentBean(autowiredBeanName, beanName);
autowiredBeanNames.clear();
catch (BeansException ex)
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor#postProcessPropertyValues实现注解给属性赋值:
从上面看到了,Bean已经解析拿到了注解的一些元信息,因此此处就调用一些处理器的postProcessPropertyValues方法,来给赋值了:
//AutowiredAnnotationBeanPostProcessor:这里就是解析该Bean的Autowired信息,然后给inject进去
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try
metadata.inject(bean, beanName, pvs);
catch (BeanCreationException ex)
throw ex;
catch (Throwable ex)
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
return pvs;
//CommonAnnotationBeanPostProcessor:逻辑和上面一毛一样,它处理的JSR-250的注解,比如@Resource
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException
InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
try
metadata.inject(bean, beanName, pvs);
catch (Throwable ex)
throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
return pvs;
//RequiredAnnotationBeanPostProcessor:它就是去校验,标注了@Required注解的,必须是是存在这个Bean的
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException
if (!this.validatedBeanNames.contains(beanName))
if (!shouldSkip(this.beanFactory, beanName))
List<String> invalidProperties = new ArrayList<>();
for (PropertyDescriptor pd : pds)
if (isRequiredProperty(pd) && !pvs.contains(pd.getName()))
invalidProperties.add(pd.getName());
if (!invalidProperties.isEmpty())
throw new BeanInitializationException(buildExceptionMessage(invalidProperties, beanName));
this.validatedBeanNames.add(beanName);
return pvs;
InjectionMetadata#inject处理依赖注入:
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty())
boolean debug = logger.isDebugEnabled();
for (InjectedElement element : elementsToIterate)
if (debug)
logger.debug("Processing injected element of bean '" + beanName + "': " + element);
// 主要的方法,还是在InjectedElement#inject里
element.inject(target, beanName, pvs);
InjectedElement实现如下:
这里我们就以最常用的AutowiredFieldElement为例讲解(它是一个普通内部类,为private的):
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable
// 拿到这个字段名
Field field = (Field) this.member;
Object value;
// 大多数情况下,这里都是false
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");
// 转换器,没有手动注册,默认都是SimpleTypeConverter===============
TypeConverter typeConverter = beanFactory.getTypeConverter();
try
// 把当前bean所依赖的这个Bean解析出来(从Spring容器里面拿,或者别的地方获取吧~~~)
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
catch (BeansException ex)
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
synchronized (this)
if (!this.cached)
// 如果已经拿到了这个Bean实例,
if (value != null || this.required)
this.cachedFieldValue = desc;
// 把该Bean的依赖关系再注册一次
registerDependentBeans(beanName, autowiredBeanNames);
// 因为是按照类型注入,所以肯定只能指导一个这个的依赖Bean,否则上面解析就已经报错了
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;
// 给该对象的该字段赋值。注意这里makeAccessible设置为true了,所以即使你的字段是private的也木有关系哦~~~
if (value != null)
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
initializeBean进行Bean的初始化工作
上面步骤已经完成了Bean的属性的赋值工作,接下里就进行Bean的一些初始化工作,其中包括:
1:Bean后置处理器初始化
2:Bean的一些初始化方法的执行init-method等等
3:Bean的实现的声明周期相关接口的属性注入
protected Object initializeBean(final String beanName, fin以上是关于Bean生命周期流程--下的主要内容,如果未能解决你的问题,请参考以下文章