Spring Bean生命周期之属性赋值阶段详解

网友投稿 780 2022-10-24

Spring Bean生命周期之属性赋值阶段详解

Spring Bean生命周期之属性赋值阶段详解

目录前言属性自动装配属性赋值前回调属性的真正赋值总结

前言

上节在谈论Bean的实例化过程时,在说明实例化后阶段时只是粗略地看了一下populateBean,并未展开分析。本节接着populateBean开始分析对象赋值阶段的事情。

populateBean其实主要做了以下几件事:

Bean实例化后回调,来决定是否进行属性赋值 (上节分析过了)对属性进行自动装配InstantiationAwareBeanPostProcessor属性赋值前回调属性的真正赋值

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {

//省略无关代码

// 1、 Bean实例化后回调,来决定是否进行属性赋值

if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {

for (BeanPostProcessor bp : getBeanPostProcessors()) {

if (bp instanceof InstantiationAwareBeanPostProcessor) {

InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;

if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {

return;

}

}

}

}

PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

//2、对属性进行自动装配

int resolvedAutowireMode = mbd.getResolvedAutowireMode();

if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {

MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

// Add property values based on autowire by name if applicable.

if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {

autowireByName(beanName, mbd, bw, newPvs);

}

// Add property values based on autowire by type if applicable.

if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {

autowireByType(beanName, mbd, bw, newPvs);

}

pvs = newPvs;

}

boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();

boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

//3、InstantiationAwareBeanPostProcessor属性赋值前回调

PropertyDescriptor[] filteredPds = null;

if (hasInstAwareBpps) {

if (pvs == null) {

pvs = mbd.getPropertyValues();

}

for (BeanPostProcessor bp : getBeanPostProcessors()) {

if (bp instanceof InstantiationAwareBeanPostProcessor) {

InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;

PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);

if (pvsToUse == null) {

if (filteredPds == null) {

filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);

}

pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);

if (pvsToUse == null) {

return;

}

}

pvs = pvsToUse;

}

}

}

//省略无关代码

if (pvs != null) {

//属性的赋值

applyPropertyValues(beanName, mbd, bw, pvs);

}

}

属性自动装配

PropertyValues 对bd中属性的封装,可以理解为bd中属性键值均由其保存,其常用实现类为MutablePropertyValues,在BeanDefinition的概述及使用 有介绍其使用,可点击查看

//这里的bd是已经执行过合并BeanDefinition操作了

//如果bd存在属性 则获取

PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

//获取bd的自动注入模式

//注入模式有四种:

//1.构造函数注入 2、按照名称注入 3、按照类型注入 4、不注入(默认,依然可能会被注解驱动注入)

int resolvedAutowireMode = mbd.getResolvedAutowireMode();

//如果是按名称注入或类型注入时

if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {

MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

//按名称注入

if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {

autowireByName(beanName, mbd, bw, newPvs);

}

// Add property values based on autowire by type if applicable.

if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {

//按类型注入,基本上这种比较常用

autowireByType(beanName, mbd, bw, newPvs);

}

pvs = newPvs;

}

下面我们分别来大致看下autowireByName及autowireByType 熟悉下实现原理

autowireByName

protected void autowireByName(

String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

//获取属性名称

String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);

//遍历属性名称

for (String propertyName : propertyNames) {

//如果属性名称已在beanDefinitionMap中,说明其是bd 并已被注册待IoC容器

if (containsBean(propertyName)) {

//根据名称获取其bean对象

Object bean = getBean(propertyName);

//以键值方法赋值到pvs

pvs.add(propertyName, bean);

// 这里是维护dependentBeanMap、dependenciesForBeanMap两个集合,

// 这里不再展开 在说到LifecycleProcessor时再展开

registerDependentBean(propertyName, beanName);

//省略日志输出

}

else {

//省略日志输出

}

}

}

autowireByType

按类型注入稍显复杂些,但流程上与按名称注入类似

protected void autowireByType(

String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

//类型转换器

TypeConverter converter = getCustomTypeConverter();

if (converter == null) {

converter = bw;

}

Set autowiredBeanNames = new LinkedHashSet<>(4);

//依然是获取属性名称

String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);

//遍历属性名称

for (String propertyName : propertyNames) {

try {

//获取属性描述对象

PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);

//不对Object类型做注入,因此这里判断条件如下

if (Object.class != pd.getPropertyType()) {

MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);

boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);

DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);

//解析依赖

Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);

if (autowiredArgument != null) {

//以键值方法赋值到pvs

pvs.add(propertyName, autowiredArgument);

}

for (String autowiredBeanName : autowiredBeanNames) {

// 这里是维护dependentBeanMap、dependenciesForBeanMap两个集合,

// 这里不再展开 在说到LifecycleProcessor时再展开

registerDependentBean(autowiredBeanName, beanName);

//省略日志输出

}

autowiredBeanNames.clear();

}

}

catch (BeansException ex) {

//省略异常信息

}

}

接下来我们进入到resolveDependency,大致分析下解析依赖的主要流程

DefaultListableBeanFactory#resolveDependency

public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,

@Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());

//如果依赖类型是Optional

if (Optional.class == descriptor.getDependencyType()) {

return createOptionalDependency(descriptor, requestingBeanName);

}

//如果依赖类型是ObjectFactory或ObjectProvider

else if (ObjectFactory.class == descriptor.getDependencyType() ||

ObjectProvider.class == descriptor.getDependencyType()) {

return new DependencyObjectProvider(descriptor, requestingBeanName);

}

//如果依赖类型是Inject

else if (javaxInjectProviderClass == descriptor.getDependencyType()) {

return new jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);

}

else {

Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(

descriptor, requestingBeanName);

if (result == null) {

//实际执行解析依赖的逻辑代码

result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);

}

return result;

}

}

@Nullable

public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,

@Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);

try {

Object shortcut = descriptor.resolveShortcut(this);

if (shortcut != null) {

return shortcut;

}

//获取依赖类型

Class> type = descriptor.getDependencyType();

//获取依赖类型的默认值,如@Value注解 可提供默认值

Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);

if (value != null) {

//如果默认值是String类型

if (value instanceof String) {

//从配置文件中解析出指定key的数据

String strVal = resolveEmbeddedValue((String) value);

BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);

value = evaluateBeanDefinitionString(strVal, bd);

}

//类型转换器 用于转换类型,如配置文件中声明的是字符串类型的数字,而java中使用Integer接收,则类型转换器就派上用场了

TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());

return (descriptor.getField() != null ?

converter.convertIfNecessary(value, type, descriptor.getField()) :

converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));

}

//解析出类型是Stream、Map、数组、Collection等集合类型的依赖。解析的思路很类似 即去IoC容器中 查找集合类实际泛型对应的Bean

Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);

if (multipleBeans != null) {

return multipleBeans;

}

//这里主要是查找单实例Bean的,如果某个类型的Bean有多个,这里会被全部查找出来,因此使用Map接收

Map matchingBeans = findAutowireCandidates(beanName, type, descriptor);

if (matchingBeans.isEmpty()) {

if (isRequired(descriptor)) {

raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);

}

return null;

}

String autowiredBeanName;

Object instanceCandidate;

//如果查找出的Bean有多个,

if (matchingBeans.size() > 1) {

//找出标注了@Primary的那个Bean名称,作为查找出的Bean

autowiredBeanName = dhttp://etermineAutowireCandidate(matchingBeans, descriptor);

if (autowiredBeanName == null) {

if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {

//如果没有@Primary注解标注,那么抛出NoUniqueBeanDefinitionException

return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);

}

else {

return null;

}

}

instanceCandidate = matchingBeans.get(autowiredBeanName);

}

else {

//如果查找出http://的Bean只有1个 那么说明找到了。

Map.Entry entry = matchingBeans.entrySet().iterator().next();

autowiredBeanName = entry.getKey();

instanceCandidate = entry.getValue();

}

if (autowiredBeanNames != null) {

autowiredBeanNames.add(autowiredBeanName);

}

if (instanceCandidate instanceof Class) {

instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);

}

Object result = instanceCandidate;

if (result instanceof NullBean) {

if (isRequired(descriptor)) {

raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);

}

result = null;

}

if (!ClassUtils.isAssignableValue(type, result)) {

throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());

}

return result;

}

finally {

ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);

}

}

可以看出resolveDependency方法还是很强大的,无论是单一类型对象还是集合类型对象,无论是Optional类型还是延迟加载ObjectFactory类型 其均可以解析出来。

属性赋值前回调

//boolean值 判断有没有InstantiationAwareBeanPostProcessor存在

boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();

// 这是 是否依赖检查的标记 不是我们此次的重点

boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

PropertyDescriptor[] filteredPds = null;

//IoC容器中如果存在InstantiationAwareBeanPostProcessor

if (hasInstAwareBpps) {

if (pvs == null) {

pvs = mbd.getPropertyValues();

}

//遍历BeanPostProcessor,找到InstantiationAwareBeanPostProcessor类型

for (BeanPostProcessor bp : getBeanPostProcessors()) {

if (bp instanceof InstantiationAwareBeanPostProcessor) {

InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;

//postProcessProperties、postProcessPropertyValues两个方法含义类似。如果postProcessProperties未被重写 则执行postProcessPropertyValues方法

PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);

if (pvsToUse == null) {

if (filteredPds == null) {

filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);

}

pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);

if (pvsToUse == null) {

return;

}

}

pvs = pvsToUse;

}

}

}

这里针对一个小案例说明下postProcessPropertyValues和postProcessProperties的使用

需求:将注入的user对象中name属性由wojiushiwo修改为abc

实体对象User

@Data

@ToString

public class User {

private String name;

private Integer age;

public User() {

}

public User(String name, Integer age) {

this.name = name;

this.age = age;

}

}

public class MyInstantiationBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

@Override

public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {

if(ObjectUtils.nullSafeEquals("user",beanName) && User.class.equals(bean.getClass())){

final MutablePropertyValues propertyValues;

if(pvs instanceof MutablePropertyValues){

propertyValues= (MutablePropertyValues) pvs;

}else{

propertyValues=new MutablePropertyValues();

}

if(propertyValues.contains("name")){

propertyValues.removePropertyValue("name");

propertyValues.addPropertyValue("name","abcd");

}

http:// return propertyValues;

}

return null;

}

}

public class BeanPostProcessDemo {

public static void main(String[] args) {

BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class);

beanDefinitionBuilder.addPropertyValue("name", "wojiushiwo");

beanDefinitionBuilder.addPropertyValue("age", 20);

// 获取 AbstractBeanDefinition

AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();

// 附加属性(

beanDefinition.setAttribute("name", "我是附加属性");

// 当前 BeanDefinition 来自哪里(辅助作用)

beanDefinition.setSource(BeanPostProcessDemo.class);

DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

beanFactory.addBeanPostProcessor(new MyInstantiationBeanPostProcessor());

// 注册 User 的 BeanDefinition

beanFactory.registerBeanDefinition("user", beanDefinition);

User user = beanFactory.getBean("user", User.class);

System.out.println(user);

}

}

输出结果:

User(name=abcd, age=20)

属性的真正赋值

if (pvs != null) {

//将从前面步骤得到的pvs 赋值到beanWrapper中以实现属性赋值,这部分具体源码这里不展开了

applyPropertyValues(beanName, mbd, bw, pvs);

}

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:一个轻量级的版本更新框架
下一篇:BigNews: Android增量升级/增量更新框架
相关文章

 发表评论

暂时没有评论,来抢沙发吧~