spring源码:bean的创建
程序员文章站
2022-05-24 16:09:38
...
spring源码:bean的创建
从doGetBean()方法中可以知道,bean会根据不同的scope进行bean创建,但真实创建bean实例的是createBean()方法。下面我们就跟踪一下这个方法:
createBean()源码
AbstractAutowireCapableBeanFactory.java
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 确定并加载bean的class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 准备覆盖的方法
try {
mbdToUse.prepareMethodOverrides();
}
catch ...
try {
// 给 Bean Post 处理器一个机会来返回代理而不是目标 Bean 实例。
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
//应用初始化前的后处理器,如果处理器中返回了AOP的代理对象,则直接返回该单例对象,不需要继续创建
if (bean != null) {
return bean;
}
}
catch ....
try {
//创建bean对象
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch ...
catch ...
}
}
上面代码对应步骤为:
- 根据设置的class属性或者根据className来解析到class
- 对override属性进行标记和验证(bean XML配置中的lookup-method和replace-method属性)
- 应用初始化前的后处理器,如果处理器中返回了AOP的代理对象,则直接返回该单例对象,不需要继续创建
- 创建bean
从上面知道创建bean的代码被封装在doCreateBean()中。
doCreateBean()源码
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// 1. 先从factoryBeanInstanceCache缓存中尝试获取
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
// 2. 如果缓存中不存在,则根据bean对应的策略创建新的实例,如:工厂方法、构造器自动注入、简单初始化
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;
}
// 3. 应用MergedBeanDefinitionPostProcessor 后处理器,合并bean的定义信息
// Autowire等注解信息就是在这一步完成预解析,并且将注解需要的信息放入缓存
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch ...
mbd.postProcessed = true;
}
}
// 4. 依赖处理
// 是否需要提前曝光 = 单例&允许循环依赖&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");
}
//为了避免循环依赖,在bean初始化完成前,就将创建bean实例的ObjectFactory放入工厂缓存(singletonFactories)
// AOP就是在这里将advice动态织入到bean中
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 5. 对bean属性进行填充,注入bean中的属性,会递归初始化依赖的bean
Object exposedObject = bean;
try {
// ----------- 填充属性 --------
populateBean(beanName, mbd, instanceWrapper);
// --------------bean的初始化------------------
//调用初始化方法,比如init-method、注入Aware对象、应用后处理器
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch ....
// 6. 循环依赖检查
if (earlySingletonExposure) {
//从提前曝光的bean缓存中查询bean,目的是验证是否有循环依赖存在
//如果存在循环依赖,也就是说该bean已经被其他bean递归加载过,放入了提早曝光的bean缓存中
Object earlySingletonReference = getSingleton(beanName, false);
//只有检测到循环依赖的情况下,earlySingletonReference才不会为null
if (earlySingletonReference != null) {
//如果exposedObject没有在 initializeBean 初始化方法中改变,也就是没有被增强
if (exposedObject == 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);
}
}
//因为bean创建后,其依赖的bean一定也是已经创建的
//如果actualDependentBeans不为空,则表示依赖的bean并没有被创建完,即存在循环依赖
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,...);
}
}
}
}
// 7. 注册DisposableBean,对应xml中的 destroy-method,以便的销毁时调用
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch ...
return exposedObject;
}
以上方法的步骤为:
- 如果是单例则首先清除缓存
- 实例化bean,并使用BeanWarpper包装
- 如果存在工厂方法,则使用工厂方法实例化
- 如果有多个构造函数,则根据传入的参数确定构造函数进行初始化
- 使用默认的构造函数初始化
- 应用MergedBeanDefinitionPostProcessor,Autowired注解就是在这样完成的解析工作
- 依赖处理。如果A和B存在循环依赖,那么Spring在创建B的时候,需要自动注入A时,并不会直接创建再次创建A,而是通过放入缓存中A的ObjectFactory来创建实例,这样就解决了循环依赖的问题
- 属性填充。所有需要的属性都在这一步注入到bean
- 循环依赖检查
- 注册DisposableBean。如果配置了destroy-method,这里需要注册,以便在销毁时调用
- 完成创建并返回
从上面的步骤可以知道bean的创建主要是三步:- bean的实例化
- 实例化后bean属性的填充
- bean的初始化
下面我们一个一个进行解析
1.bean的实例化
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 获取bean class
Class<?> beanClass = resolveBeanClass(mbd, beanName);
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);
}
// 如果工厂方法不为空(RootBeanDefinition中存在factoryMethodNam属性,或者配置文件中配置了factory-method),则使用工厂方法初始化策略
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) {
//如果一个类有多个构造函数,每个构造函数都有不同的参数,所以调用前需要先根据参数锁定构造函数或对应的工厂方法
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
//如果已经解析过则使用解析好的构造函数方法不需要再次锁定
if (resolved) {
if (autowireNecessary) {
//构造函数自动注入
return autowireConstructor(beanName, mbd, null, null);
}
else {
//使用默认构造函数构造
return instantiateBean(beanName, mbd);
}
}
// 根据参数解析构造函数
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
//构造函数自动注入
return autowireConstructor(beanName, mbd, ctors, args);
}
// 使用默认构造函数
return instantiateBean(beanName, mbd);
}
从上面的代码发现实例化bean的方式就三种:
- 如果存在工厂方法,则使用工厂方法实例化
- 如果有多个构造函数,则根据传入的参数确定构造函数进行初始化
- 使用默认的构造函数初始化
主要涉及的方法:
instantiateUsingFactoryMethod()、autowireConstructor()、instantiateBean()
autowireConstructor()方法
ConstructorResolver.java
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
Constructor<?> constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;
/**
* 1. 构造参数的确定
* 1.1 调用getBean方法时传入
* 1.2 缓存中获取
* 1.3 配置文件中获取
*/
//explicitArgs通过getBean方法传入
//如果getBean方法调用的时候指定方法参数那么直接使用
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {
//如果getBean方法没有传入参数,则尝试从配置文件中解析
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// 从缓存中获取
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
//配置的构造函数参数
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
if (argsToResolve != null) {
// 解析参数类型,如构造函数A(int,int)通过此方法后就会把配置中的("1","1")转换成(1,1)
//缓存中的值可能是原始值也可能是最终值
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
}
}
//没有被缓存
if (constructorToUse == null) {
// 需要解析构造函数。
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;
int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
//配置文件中配置的构造函数参数
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
//用于承载解析后的参数值
resolvedValues = new ConstructorArgumentValues();
//能解析到的参数个数
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
/**
* 2. 构造函数的确定
*
*/
// Take specified constructors, if any.
Constructor<?>[] candidates = chosenCtors;
if (candidates == null) {
Class<?> beanClass = mbd.getBeanClass();
try {
candidates = (mbd.isNonPublicAccessAllowed() ?
beanClass.getDeclaredConstructors() : beanClass.getConstructors());
}
catch ...
}
//构造函数排序,public构造函数优先参数数量降序、非public构造函数参数数量降序
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
LinkedList<UnsatisfiedDependencyException> causes = null;
for (Constructor<?> candidate : candidates) {
Class<?>[] paramTypes = candidate.getParameterTypes();
if (constructorToUse != null && argsToUse.length > paramTypes.length) {
// 如果已经找到选用的构造参数,而且传入的参数个数大于当前的构造参数个数则终止,因为构造函数已经按照参数个数降序排列
break;
}
if (paramTypes.length < minNrOfArgs) {
//参数个数不相等
continue;
}
ArgumentsHolder argsHolder;
if (resolvedValues != null) {
try {
//有参数,则根据参数类型和参数名构造对象
//注释上获取参数名称
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
if (paramNames == null) {
//参数名称探测器
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
//获取构造参数名称
paramNames = pnd.getParameterNames(candidate);
}
}
///根据名称和数据类型创建参数持有者
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring);
}
catch...
}
else {
// Explicit arguments given -> arguments length must match exactly.
if (paramTypes.length != explicitArgs.length) {
continue;
}
//构造函数没有参数
argsHolder = new ArgumentsHolder(explicitArgs);
}
//检查是否有不确定性的构造函数存在,例如不同构造函数的参数为父子关系
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// 如果它代表着当前最接近的匹配则选择作为构造函数
if (typeDiffWeight < minTypeDiffWeight) {
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousConstructors = null;
}
else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
if (ambiguousConstructors == null) {
ambiguousConstructors = new LinkedHashSet<>();
ambiguousConstructors.add(constructorToUse);
}
ambiguousConstructors.add(candidate);
}
}
if (constructorToUse == null) {
if (causes != null) {
UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName,..);
}
else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,..);
}
if (explicitArgs == null) {
//将解析的构造函数加入缓存
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
try {
//使用策略的instantiate方法,实例化bean
final InstantiationStrategy strategy = beanFactory.getInstantiationStrategy();
Object beanInstance;
if (System.getSecurityManager() != null) {
final Constructor<?> ctorToUse = constructorToUse;
final Object[] argumentsToUse = argsToUse;
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
strategy.instantiate(mbd, beanName, beanFactory, ctorToUse, argumentsToUse),
beanFactory.getAccessControlContext());
}
else {
beanInstance = strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
}
//将构造的实例加入BeanWrapper中
bw.setBeanInstance(beanInstance);
return bw;
}
catch ...
}
此方法的主要逻辑为:
- 构造参数的确定
- 构造函数的确定
- 根据构造函数转换传入参数的类型
- 构造函数不确定性的验证
- 根据实例化策略及确定的构造函数和参数实例化bean.
instantiateBean()无参构造
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
}
else {
//实例化
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
从上面得知,不过是自动注入的,还是默认无参的构造函数都是调用实例化策略的instantiate()方法实例化bean的,那下面就去看看这个方法
instantiate()真正实现实例化
SimpleInstantiationStrategy.java
// 如果有需要覆盖或动态替换的方法,则使用cglib进行动态代理(因为可以在创建代理的同时将动态方法织入到类中)
//但如果没有需要动态改变的方法,为了方便直接使用反射
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}
else {
constructorToUse = clazz.getDeclaredConstructor();
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch ...
}
}
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// 使用了replace或者lookup的配置方法
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
通过SimpleInstantiationStrategy策略的instantiate()真正实现实例化了bean.
2.populateBean()填充属性
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;
}
}
// 给InstantiationAwareBeanPostProcessors最后一次机会在属性注入前修改Bean的属性值
// 1.具体通过调用postProcessAfterInstantiation方法,如果调用返回false,表示不必继续进行依赖注入,直接返回
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//判断是否继续填充 bean
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
//如果后处理器发出停止填充命令则终止后续的执行
if (!continueWithPropertyPopulation) {
return;
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// 根据Bean配置的依赖注入方式完成注入,默认是0,即不走以下逻辑,所有的依赖注入都需要在xml文件中有显式的配置
// 如果设置了相关的依赖装配方式,会遍历Bean中的属性,根据类型或名称来完成相应注入,无需额外配置
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
// 深拷贝当前已有的配置
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 根据名称进行注入
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// 根据类型进行注入
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
// 结合注入后的配置,覆盖当前配置
pvs = newPvs;
}
//3.后处理器是否已经初始化
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;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
// 检查是否满足相关依赖关系,对应的depends-on属性,需要确保所有依赖的Bean先完成初始化
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
if (pvs != null) {
// 4.将pvs上所有的属性填充到BeanWrapper对应的Bean实例中,注意到这一步,TestBean的student属性还是RuntimeBeanReference,即还未解析实际的Student实例
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
此方法的代码步骤:
- 执行InstantiationAwareBeanPostProcessors处理器的postProcessAfterInstantiation()方法,控制程序是否继续进行属性填充。
- 根据注入类型(byName\byType),提取依赖的bean,并统一存入PropertyValues中。
- 执行InstantiationAwareBeanPostProcessors处理器的postProcessPropertyValues()方法,在获取属性完成 填充属性前 对属性的再次处理。
- 将所有的PropertyValues中的属性填充至BeanWrapper中。
这里有三个关键函数autowireByName、autowireByType、applyPropertyValues,下面就这个三个函数展开。
autowireByName()
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) {
if (containsBean(propertyName)) {
// 递归初始化相关Bean
Object bean = getBean(propertyName);
// 根据名称添加到pvs中
pvs.add(propertyName, bean);
// 注册依赖关系
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");
}
}
}
}
autowireByType()
protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
// 获取类型转换器
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
// 类似的,过滤出满足装配条件的Bean属性
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()) {
// 获取相关的setter方法参数
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// // 定义是否允许懒加载。
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);
if (logger.isDebugEnabled()) {
logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +
propertyName + "' to bean named '" + autowiredBeanName + "'");
}
}
autowiredBeanNames.clear();
}
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}
applyPropertyValues()
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (pvs.isEmpty()) {
return;
}
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
MutablePropertyValues mpvs = null;
List<PropertyValue> original;
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
//如果mpvs中的值已经被转换为对应的类型那么可以直接设置到beanwapper中
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {
bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
original = mpvs.getPropertyValueList();
}
else {
//如果pvs并不是使用MutablePropertyValues封装的类型,那么直接使用原始的属性获取方法
original = Arrays.asList(pvs.getPropertyValues());
}
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
//获取对应的解析器
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// Create a deep copy, resolving any references for values.
List<PropertyValue> deepCopy = new ArrayList<>(original.size());
boolean resolveNecessary = false;
//遍历属性,将属性转换为对应类的对应属性的类型
for (PropertyValue pv : original) {
if (pv.isConverted()) {
deepCopy.add(pv);
}
else {
String propertyName = pv.getName();
Object originalValue = pv.getValue();
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// Possibly store converted value in merged bean definition,
// in order to avoid re-conversion for every created bean instance.
if (resolvedValue == originalValue) {
if (convertible) {
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
else if (convertible && originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
}
// Set our (possibly massaged) deep copy.
try {
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
3. bean的初始化
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
//对特殊的bean处理:Aware、BeanClassLoaderAware、BeanFactoryAware
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//应用后处理器
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
///**用户自定义的init方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//应用后处理器
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
上一篇: 使用音箱需要的注意几点要素
下一篇: 选购产品!着眼分辨率选好扫描仪
推荐阅读
-
Spring boot创建自定义starter的完整步骤
-
Spring中Bean的生命周期使用解析
-
spring如何使用命名空间p简化bean的配置
-
JSP 开发之Spring Boot 动态创建Bean
-
spring5 源码深度解析----- 被面试官给虐懵了,竟然是因为我不懂@Configuration配置类及@Bean的原理
-
Spring学习之Bean的装配多种方法
-
基于Spring注解的上下文初始化过程源码解析(一)
-
SpringBoot 源码解析 (七)----- Spring Boot的核心能力 - SpringBoot如何实现SpringMvc的?
-
SpringBoot 源码解析 (六)----- Spring Boot的核心能力 - 内置Servlet容器源码分析(Tomcat)
-
通过实例解析spring bean之间的关系