三Spring-ioc容器--4依赖注入及初始化源码分析
三Spring-ioc容器--4依赖注入及初始化源码分析
属性赋值(依赖注入)
DCB4.2 autowireByName/Type
这里是xml配置里的自动装配autowiring。配置bean后,对类内属性byType或者byName等。
/** ---------------------------xml配置的bean的autowiring自动装配-------------------------------*/
//获取beandefinition内的属性
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
//DCB4.2 autowireByName
//处理bean的autowire的类型,有byname、no、bytype、constructor等
// 默认是AUTOWIRE_NO,因此不会走下面的autowireByName、autowireByType方法,
// 需要xml显式配置,如autowire="byType"
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) { //1
//如果需要autowire注入,将mbd中属性值pvs转换为可变属性值对象MutablePropertyValues
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
//byName模式autowire完成注入
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
//DCB4.2.1 autowireByName
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
//DCB4.2.2 autowireByType
autowireByType(beanName, mbd, bw, newPvs);
}
//用自动装配autowire后新的配置,覆盖老的配置
pvs = newPvs;
} //1
DCB4.2.1 autowireByName
AbstractAutowireCapableBeanFactory
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
//DCB4.2.1.1 unsatisfiedNonSimpleProperties,获取需要自动注入的属性名称
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
if (containsBean(propertyName)) {
/**---------------------------------递归调用getBean,获取属性对象--------------------------- */
//调用getBean向IOC容器中获取指定名称的bean实例,触发迭代的过程,初始化
Object bean = getBean(propertyName);
//为指定名称的属性propertyName赋值,并将kv对添加入MutablePropertyValues中
pvs.add(propertyName, bean);
//详细见TAG1.5,指定名称属性注册依赖bean的名称
registerDependentBean(propertyName, beanName);
if (logger.isTraceEnabled()) {
logger.trace("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");
}
}
}
}
上面autowireByName逻辑,是获取需要注入的属性的beanname,然后递归调用getBean(name)获取bean,然后将property:bean对应的属性和bean对象对加入MutablePropertyValues中。
DCB4.2.1.1 unsatisfiedNonSimpleProperties
该方法中,对bean属性过滤,得到需要autowiring自动注入的属性。主要包括具有setter方法的属性、非简单类型的属性(如void、url等八大基本数据类型和其包装类型为简单类型)。
protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
Set<String> result = new TreeSet<>();
// 获取bean 的property 属性
PropertyValues pvs = mbd.getPropertyValues();
// 获取 bw 中的属性描述
PropertyDescriptor[] pds = bw.getPropertyDescriptors();
for (PropertyDescriptor pd : pds) {
// if pd属性具有set方法 && 依赖检查中没有被忽略 && 没有被配置成 property 属性 && 不是简单类型
if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
!BeanUtils.isSimpleProperty(pd.getPropertyType())) {
// 添加到需要装配的集合中
result.add(pd.getName());
}
}
// 返回需要自动装配的bean集合
return StringUtils.toStringArray(result);
}
DCB4.2.2 autowireByType
protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
//获取自定义的type转换器
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
//如果没有自定义,设置为BeanWrapper
converter = bw;
}
//需要自动注入属性的bean的names
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
//选择需要自动注入autowiring的属性名称
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) { //1
try { //2
//创建BeanWrapper中的属性propertyName的属性描述器
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类型的属性,autowiring注入
if (Object.class != pd.getPropertyType()) { //3
//获取属性的setter方法
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// Do not allow eager init for type matching in case of a prioritized post-processor.
boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
//创建要被自动注入的依赖dependency描述器
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
//DCB4.2.2.1 resolveDependency
//根据容器的bean定义,解析依赖关系,获取要被注入的bean对象
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
//属性name:属性bean的kv对,添加入MutablePropertyValues中
pvs.add(propertyName, autowiredArgument);
}
//需要自动注入的beannames
for (String autowiredBeanName : autowiredBeanNames) { //4
//注册依赖关系
registerDependentBean(autowiredBeanName, beanName);
if (logger.isTraceEnabled()) {
logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" +
propertyName + "' to bean named '" + autowiredBeanName + "'");
}
} //4
autowiredBeanNames.clear();
} //3
} //2
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
} //1
}
autowireByType方法主要逻辑,是获取需要自动注入autowiring的属性名称,然后,针对属性执行resolveDependency,获得到依赖的bean实例。然后把属性名:bean的kv对添加入MutablePropertyValues中,并registerDependentBean注册依赖关系。
DCB4.2.2.1 resolveDependency
AutowireCapableBeanFactory
/**参数分析:
DependencyDescriptor:依赖的描述符(可以是field、method、costructor);
requestingBeanName:需要解决依赖问题的beanname;
Set<String> autowiredBeanNames:用来解决给定的DependencyDescriptor的已经autowired的beans,它们的names需要添 加入这个set;
TypeConverter:这个类型转换器,用来填充数组或者集合
return:返回解析过的对象(就是依赖的对象)
*/
@Nullable
Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException;
resolveDependency作用,是解析工厂中定义的bean的特定的依赖。
DefaultListableBeanFactory
@Override
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
if (Optional.class == descriptor.getDependencyType()) {
return createOptionalDependency(descriptor, requestingBeanName);
}
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
//上面对特殊的依赖类型进行处理,一般通用处理,执行doResolveDependency
else {
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
//一般为空,
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
然后执行doResolveDependency
@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> 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注解的属性----------------------------------*/
// 取值@Value注解中的value属性中的值,这里取出的值是未经修改的值,即带有 ${} 标签的值。如果descriptor未被@Value标注,则返回null
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
try {
return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
}
catch (UnsupportedOperationException ex) {
// A custom TypeConverter which does not support TypeDescriptor resolution...
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
}
/** -------------------------------------处理集合类型----------------------------------*/
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
/** -------------------------------------处理正常的依赖对象类型----------------------------------*/
//DCB4.2.2.1.1 findAutowireCandidates
//matchingBeans<beanName,bean> 查找所有类型为type的实例
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
/** -------------根据类型type找到多个bean,然后按照名字来匹配多个bean,从中找出一个用来注入-------*/
if (matchingBeans.size() > 1) {
/** 挑选符合条件的bean的逻辑:
首先,选择标识为primary的bean;
如果没有,选择@priority注解、且优先级最高的bean(该注解可以不标识,如果有,不允许同一优先级的bean*/
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
}
else {
// In case of an optional Collection/Map, silently ignore a non-unique case:
// possibly it was meant to be an empty collection of multiple regular beans
// (before 4.3 in particular when we didn't even look for collection beans).
return null;
}
}
//根据匹配到的属性bean的名称autowiredBeanName,从缓存中找到对应的实例instanceCandidate
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
/** --------------------------只匹配到一个bean--------------------------*/
else {
// We have exactly one match.
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
if (autowiredBeanNames != null) {
//将待装配的Bean名称放入autowiredBeanNames集合里
autowiredBeanNames.add(autowiredBeanName);
}
if (instanceCandidate instanceof Class) {
//DCB4.2.2.1.2 descriptor.resolveCandidate
//该处调用getBean获取bean--------->beanFactory.getBean(beanName)
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);
}
}
DCB4.2.2.1.1 findAutowireCandidates
//DefaultListableBeanFactory#findAutowireCandidates
protected Map<String, Object> findAutowireCandidates(
@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
// 根据 Class 类型,找到对应的候选beanName,
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
// 这里我们一般不会涉及。如果注入的是 resolvableDependencies key类型,则会装配成value类型
for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
Class<?> autowiringType = classObjectEntry.getKey();
if (autowiringType.isAssignableFrom(requiredType)) {
Object autowiringValue = classObjectEntry.getValue();
autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
if (requiredType.isInstance(autowiringValue)) {
result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
break;
}
}
}
// 遍历候选的beanName
for (String candidate : candidateNames) {
// 不是自引用 && 允许被注入(autowire-candidate 标签指定)
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
// 将结果添加到result中
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
// 如果目前找到的匹配的bean集合为空
if (result.isEmpty()) {
// Array || Collection || Map 。即是否表示多个bean的集合类型
boolean multiple = indicatesMultipleBeans(requiredType);
// Consider fallback matches if the first pass failed to find anything...
DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
for (String candidate : candidateNames) {
// 非自引用 && 允许被注入 && (非集合类 || 解析 @Qualifier 注解或者 javax.inject.Qualifier类成功)
// 这里开始分析解析的属性是否被 @Qualifier 注解或者 javax.inject.Qualifier类 限定符限定了
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) &&
(!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
// 如果还没找到 && 非集合类
if (result.isEmpty() && !multiple) {
// Consider self references as a final pass...
// but in the case of a dependency collection, not the very same bean itself.
for (String candidate : candidateNames) {
// 将自我引用视为最后一步。判断是不是自己引用自己
if (isSelfReference(beanName, candidate) &&
(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
isAutowireCandidate(candidate, fallbackDescriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
}
}
return result;
}
...
private void addCandidateEntry(Map<String, Object> candidates, String candidateName,
DependencyDescriptor descriptor, Class<?> requiredType) {
// 根据类型判断,如果是MultiElementDescriptor,获取后保存到候选列表中
if (descriptor instanceof MultiElementDescriptor) {
Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);
if (!(beanInstance instanceof NullBean)) {
candidates.put(candidateName, beanInstance);
}
}
// 如果 单例缓存中存在 || 是 StreamDependencyDescriptor 的类型 && order = true
else if (containsSingleton(candidateName) || (descriptor instanceof StreamDependencyDescriptor &&
((StreamDependencyDescriptor) descriptor).isOrdered())) {
// 调用了beanFacotory.getBean 方法获取bean
Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);
// 保存起来
candidates.put(candidateName, (beanInstance instanceof NullBean ? null : beanInstance));
}
else {
// getType 调用了beanFacotory.getBean 方法
candidates.put(candidateName, getType(candidateName));
}
}
DCB4.2.2.1.2 descriptor.resolveCandidate
DependencyDescriptor
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)
throws BeansException {
//调用getBean方法,递归方式解决bean的属性注入(或者说依赖注入过程)
return beanFactory.getBean(beanName);
}
DCB4.3 InstantiationAwareBeanPostProcessor.postProcessProperties(注解注入-6pp)
这里,bean的后置处理器执行注解注入,主要调用下面连个类。
CommonAnnotationBeanPostProcessor.postProcessProperties---处理@preDestroy,@preConstruct、@resource自动注入
AutowiredAnnotationBeanPostProcessor.postProcessProperties---处理@autowire注解、@value注解自动注入功能
//判断是否有InstantiationAwareBeanPostProcessor类
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
//检测是否需要依赖检查(目前,rootbeandefinition中的dependencycheck属性已经被弃用)
boolean needsDepCheck = (mbd.getDependencyCheck()!=AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) { //1
//如果不是
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
//获取BeanPostProcessor后置处理器对象
for (BeanPostProcessor bp : getBeanPostProcessors()) { //2
if (bp instanceof InstantiationAwareBeanPostProcessor) { //3
//找到InstantiationAwareBeanPostProcessor后置处理器
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
/**-----------------注解注入(@autowire和@resource的属性注入)---------------------------------- */
//DCB4.2 InstantiationAwareBeanPostProcessor.postProcessProperties
//执行postProcessProperties方法,对配置进行处理————对象属性依赖注入
// CommonAnnotationBeanPostProcessor.postProcessProperties
// AutowiredAnnotationBeanPostProcessor.postProcessProperties
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) { //4
if (filteredPds == null) {
//过滤需要进行依赖检查的属性描述符
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
//DCB4.3 InstantiationAwareBeanPostProcessor.postProcessPropertyValues
//新版本spring中,该方法已经陪遗弃
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
} //4
pvs = pvsToUse;
} //3
} //2
}//1
DCB4.3.1 CommonAnnotationBeanPostProcessor#postProcessProperties
这个后置处理器主要处理@preDestroy,@preConstruct、@resource自动注入。
postProcessPropertyValues方法逻辑,主要是获取@resource注解的元数据,然后,对属性inject注入。
//处理属性值
@Override
public PropertyValues postProcessProperties(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
//获取@Resource注解中配置的属性值元数据metadata
InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
try {
//DCB4.3.1.1 metadata.inject 元数据属性注入
metadata.inject(bean, beanName, pvs);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
}
return pvs;
}
private InjectionMetadata findResourceMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
// Fall back to class name as cache key, for backwards compatibility with custom callers.
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// Quick check on the concurrent map first, with minimal locking.
//先从injectionMetadataCache缓存中查找待注入的元数据--(最大限度避免资源锁定)
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
//检查找到的的元数据是否需要刷新
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
//根据clazz,重建resource的元数据
metadata = buildResourceMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
DCB4.3.1.1 metadata.inject
InjectionMetadata
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
//详见DCB2中,两个后置处理器,分别对find出的autowire和resource的元数据,存储在checkedElements中
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
for (InjectedElement element : elementsToIterate) {
//对每个待注入的element,for循环inject
element.inject(target, beanName, pvs);
}
}
}
在这里,element.inject,调用内部类中的方法:
InjectionMetadata.InjectedElement#inject()
protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)throws Throwable {
//通过字段注入
if (this.isField) {
Field field = (Field) this.member;
ReflectionUtils.makeAccessible(field);
field.set(target, getResourceToInject(target, requestingBeanName));
}
//通过方法注入
else {
if (checkPropertySkipping(pvs)) {
return;
}
try {
Method method = (Method) this.member;
ReflectionUtils.makeAccessible(method);
method.invoke(target, getResourceToInject(target, requestingBeanName));
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
DCB4.3.2 AutowiredAnnotationBeanPostProcessor #postProcessProperties
该方法逻辑:获取被@autowire注解的属性或者方法。如果是属性,通过getBean获取bean并注入;如果是方法,获取方法参数后,invoke调用method,来给属性赋值。
@Override
public PropertyValues postProcessProperties(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
//获取指定类中autowire相关注解的元信息
//该方法在DCB2中调用过,获取@autowire注解的元数据,并存入缓存中,该处是从缓存获取,然后注入操作
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
//对Bean的属性进行自动注入
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;
}
最终会调用本类中的方法:
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject
???????
//对字段进行注入
@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) {
//根据Bean名称解析缓存中的字段值
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 {
//根据容器中Bean定义,解析指定的依赖关系,获取需要依赖注入的对象
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
//线程同步,确保容器中数据一致性
synchronized (this) {
//如果当前对象没有被容器缓存
if (!this.cached) {
//获取到了当前对象的依赖对象,并且required属性为true
if (value != null || this.required) {
this.cachedFieldValue = desc;
//为指定Bean注册依赖Bean
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
//如果容器中有指定名称的Bean对象
if (beanFactory.containsBean(autowiredBeanName)) {
// 依赖对象类型和字段类型匹配,默认按类型注入
if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
//创建一个依赖对象的引用,同时缓存
this.cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
}
//如果获取的依赖关系为null,且获取required属性为false
else {
//将字段值的缓存设置为null
this.cachedFieldValue = null;
}
//容器已经对当前字段的值缓存
this.cached = true;
}
}
}
//如果字段依赖值不为null
if (value != null) {
//显式使用JDK的反射机制,设置自动的访问控制权限为允许访问
ReflectionUtils.makeAccessible(field);
//TODO 为Bean对象的字段设置值 完成了属性填充
field.set(bean, value);
}
}
}
DCB4.4 InstantiationAwareBeanPostProcessor.postProcessPropertyValues(7pp)
在新版本spring中,postProcessProperties方法已经被弃用
AutowiredAnnotationBeanPostProcessor
@Deprecated
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) {
//仍旧调用postProcessProperties
return postProcessProperties(pvs, bean, beanName);
}
DCB4.5 applyPropertyValues(设置PropertyValues)
上面过程,只是将属性保存在PropertyValues中,这里完成真正的设置属性的操作。
AbstractAutowireCapableBeanFactory
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) { //1
//如果是
mpvs = (MutablePropertyValues) pvs;
//如果mpvs中的值类型已经转换完毕,表示值能够设置到beanwrapper中
if (mpvs.isConverted()) { //2
// Shortcut: use the pre-converted values as-is.
try {
//beanwrapper通过MutablePropertyValues对bean进行属性的赋值
bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
} //2
//如果mpvs中类型没有转换,保存原属性为List<PropertyValue>
//保存原始值,等待类型转换
original = mpvs.getPropertyValueList();
} //1
else {
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) {
//如果original中的pv已经转换过,直接添加入深度拷贝deepCopy中
if (pv.isConverted()) {
deepCopy.add(pv);
}
//如果没有转换过
else {
String propertyName = pv.getName();
Object originalValue = pv.getValue();
if (originalValue == AutowiredPropertyMarker.INSTANCE) {
Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
if (writeMethod == null) {
throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
}
originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
}
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();
}
//重新转换深度拷贝的属性配置信息deepcopy为MutablePropertyValues,然后在设置入beanwrapper内,完成属性的设置
try {
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
以上过程,完成了对bean的属性的注入操作。
DCB5 initializeBean-初始化
AbstractAutowireCapableBeanFactory.initializeBean
bean实例化的后置处理,主要是aop的动态代理的创建
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 {
//DCB5.1 invokeAwareMethods
//调用aware接口,设置bean的classloader、beanname、beanfactory等信息
//该处调用的就是aware接口的setXXX方法
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//DCB5.2 applyBeanPostProcessorsBeforeInitialization---7pp
//特殊注解的支持:@postContrust,Aware接口
/** aop入口在此!
所有aop切面的父类AbstractAutoProxyCreator
有几个aop的入口类:基于配置的,基于注解的
*/
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//DCB5.3 invokeInitMethods
//initializingBean接口,afterPropertiesSet方法,init-method等属性调用点
//after调用时机早于init-method
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()) {
//DCB5.4 applyBeanPostProcessorsAfterInitialization---8pp
//为bean实例初始化之后,做一些处理
//AOP入口
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
aware接口回调
关于aware接口的作用和原理,详见2.13Aware[接口](#2.13 Aware接口)
DCB5.1 invokeAwareMethods
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
上面方法,主要是判断bean是否实现以下三种aware接口,来调用setter方法,完成beanName、beanclassloader、beanFactory属性的设置。
初始化前阶段
DCB5.2 applyBeanPostProcessorsBeforeInitialization (7pp)
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
//调用后置处理器的postProcessBeforeInitialization方法
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
对于途中属性的设置,通过调用后置处理器ApplicationContextAwareProcessor的初始化前置方法,调用aware接口的setter方法,完成属性设置。
ApplicationContextAwareProcessor
@Override
@Nullable
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
//如果bean不是这些aware的子类,那么不会在初始化之前进行任何处理
if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware ||
bean instanceof ApplicationStartupAware)) {
return bean;
}
AccessControlContext acc = null;
if (System.getSecurityManager() != null) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareInterfaces(bean);
return null;
}, acc);
}
else {
//调用aware接口的setter方法,完成初始化对属性的设置
invokeAwareInterfaces(bean);
}
return bean;
}
(获取spring内置bean,例如environment,embeddedvalueresolver等bean,需要后置处理器ACAwareProcessor的方法实现)
// 调用Aware接口
private void invokeAwareInterfaces(Object bean) {
// 判断 bean 属于那种类型,调用对应的方法
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean). (this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
初始化阶段
DCB5.3 invokeInitMethods-->afterPropertiesSet及init-method(bean的xml)
这里调用自定义的初始化方法。
自定义的初始化方法,包括如下几个:
1 bean实现InitializingBean的afterPropertiesSet方法,实现自己初始化的业务逻辑;
2 bean的xml配置中指定init-method属性,指定初始化方法(或者@Bean(initMethod=)指定初始化方法)。
*/AbstractAutowireCapableBeanFactory
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
//首先处理实现InitializingBean的afterPropertiesSet初始化方法
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.hasAnyExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
//调用afterPropertiesSet方法,初始化
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null && bean.getClass() != NullBean.class) {
//获取定义的initmethod方法名称
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.hasAnyExternallyManagedInitMethod(initMethodName)) {
//调用自定义的initMethod方法
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
从上面源码调用,可以知道invokeInitMethods的逻辑,是先调用InitializingBean的afterPropertiesSet方法;然后,调用自定义的initMethod方法。
protected void invokeCustomInitMethod(String beanName, Object bean, RootBeanDefinition mbd)
throws Throwable {
//获取自定义初始化方法Initmethod名称
String initMethodName = mbd.getInitMethodName();
Assert.state(initMethodName != null, "No init method set");
//创建Method对象
Method initMethod = (mbd.isNonPublicAccessAllowed() ?
BeanUtils.findMethod(bean.getClass(), initMethodName) :
ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));
if (initMethod == null) {
if (mbd.isEnforceInitMethod()) {
throw new BeanDefinitionValidationException("Could not find an init method named '" +
initMethodName + "' on bean with name '" + beanName + "'");
}
else {
if (logger.isTraceEnabled()) {
logger.trace("No default init method named '" + initMethodName +
"' found on bean with name '" + beanName + "'");
}
// Ignore non-existent default lifecycle methods.
return;
}
}
if (logger.isTraceEnabled()) {
logger.trace("Invoking init method '" + initMethodName + "' on bean with name '" + beanName + "'");
}
Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod, bean.getClass());
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
ReflectionUtils.makeAccessible(methodToInvoke);
return null;
});
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>)
() -> methodToInvoke.invoke(bean), getAccessControlContext());
}
catch (PrivilegedActionException pae) {
InvocationTargetException ex = (InvocationTargetException) pae.getException();
throw ex.getTargetException();
}
}
else {
try {
ReflectionUtils.makeAccessible(methodToInvoke);
//反射调用Initmethod方法
methodToInvoke.invoke(bean);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
自定义Initmethod方法的调用,通过反射实现。
初始化后阶段
DCB5.4 applyBeanPostProcessorsAfterInitialization (8pp)
AbstractAutowireCapableBeanFactory
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
//调用后置处理器的postProcessAfterInitialization--初始化后置方法
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
初始化完成阶段
SmartInitializingSingleton#afterSingletonsInstiated
当所有单例初始化完成后,执行该方法。(执行到这里时,标志bean已经是完整的bean了)
使用场合:
在所有单例bean创建并初始化完成后,IOC容器回调该方法,执行自定义操作。
……………………略
销毁阶段
DCB6 registerDisposableBeanIfNecessary
bean实例销毁与注册,供外部servlet容器调用
AbstractBeanFactory.registerDisposableBeanIfNecessary
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
DefaultSingletonBeanRegistry.registerDisposableBean
public void registerDisposableBean(String beanName, DisposableBean bean) {
synchronized (this.disposableBeans) {
this.disposableBeans.put(beanName, bean);
}
}
总结
对于创建一个bean,可以实现如下的接口,回顾每个接口对应的方法,在bean的创建过程中的调用点:
public class UserHolder implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, EnvironmentAware,InitializingBean, SmartInitializingSingleton, DisposableBean {
总结spring中bean的创建流程,如下图所示:
3.3.3 后置处理器的注册与实例化时机
PostProcessor的注册、初始化和实例化,贯穿在前述spring注册、加载bd、实例化和初始化过程中,因此需要单独提炼出其关键的过程。
spring容器在加载阶段,有一些非常重要类似于埋点的设计,这些后置处理器的设计扩展了spring容器的功能。它允许自定义不同类型的后置处理器,实现外部对bean和beandefinition的处理节点、加载时机等的干预,从而满足项目的个性化需求。
spring的IOC容器扩展点的理解:
扩展点汇总:
- beanFactoryPostProcessor:对beanFactory中的beandefinition进行修改
- bean生命周期接口,InitializingBean和DisposableBean:分别是在bean实例创建和销毁时被调用
- BeanPostProcessor:构建bean对象时调用。
- FactoryBean
PostProcessor的作用,如上:
beanFactoryPostProcessor负责为beanFactory中的beanDefinition进行修改,BeanPostProcessor负责为bean的初始化前后进行调整和自定义。
继承关系如下:
其中最重要的三大组件为:ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor等。
3.3.3.1 BeanFactoryPostProcessor
public interface BeanFactoryPostProcessor {
//参数:ConfigurableListableBeanFactory 被applicationContext使用的bf
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
在beanFactory标准化初始化后,修改applicationContext内部的beanFactory。会加载所有beandefinition,但是此时不会实例化bean。这个方法允许在beandefinition实例化之前,对beandefinition进行修改,如添加属性等。
工作原理:
applicationContext自己检测出BeanFactoryPostProcessor的beans,并在beandefinition——》bean的时候,调用这些postprocessor。
1 BeanDefinitionRegistryPostProcessor
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
//参数BeanDefinitionRegistry:被applicationContext使用的beanDefinitionRegistry
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
该类对BeanFactoryPostProcessor进行拓展,允许在常规BeanFactoryPostProcessor检测启动前,执行,来注册更多的beanDefinition。
postProcessBeanDefinitionRegistry方法,是在applicationContext初始化之后,修改其内部的beanDefinitionRegistry。所有的beandefinition被加载,但是还没有被实例化。因为是在registry的处理,因此该processor可以在下一个postprocessor开始前添加或修改beandefinition。
2 ConfigurationClassPostProcessor
该类,提供对@bean、@componentScan、@import等注解的解析支持。
3.3.3.2 BeanPostProcessor
1 InstantiationAwareBeanPostProcessor
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
//在bean实例化之前调用,如果需要返回一个代理proxy对象,就会抑制bean的正常的默认的实例化流程
//返回非空对象时候,会跳过默认的bean实例化流程
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
//在beanFactory将给定的属性应用到给定的bean之前,对其进行postProcess(提前给属性赋值)
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
throws BeansException {
return null;
}
@Deprecated
@Nullable
default PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}
}
额外提供了两个方法,在实例化前、后执行。其中调用postProcessBeforeInstatiation(),在创建bean实例之前,先尝试用后置处理器返回对象。如果返回成功,直接调用postProcessAfterInstatiation(),执行实例化后置操作。
spring实例化流程如下:
实例化时候,如果有InstantiationAwareBeanPostProcessor的BeanPostProcessor,则用它来提前实例化完成proxy的创建。成功后直接跳过默认bean的实例化。
3.3.3.3 后置处理器的执行时机
(copy)
1、InstantiationAwareBeanPostProcessor :
Spring Bean 实例化前阶段: 第一次调用后置处理器 postProcessBeforeInstantiation 方法 默认实现是判断是否需要代理放入map中
Spring Bean 实例化后置阶段: 第五次调用后置处理器 postProcessAfterInstantiation方法 属性赋值(Populate)判断是否需要属性填充
populateBean属性赋值 : 第六次调用后置处理器:postProcessPropertyValues 为bean填充属性包括依赖注入的属性
2、martInstantiationAwareBeanPostProcessor 后置处理器:
第二次调用后置处理器determineCandidateConstructors获取最优构造方法实例化对象
3、SmartInstantiationAwareBeanPostProcessor后置处理器
第四次调用后置处理器getEarlyBeanReference解决循环依赖的问题
4、InstantiationAwareBeanPostProcessor初始化后置处理器
Spring Bean 初始化前阶段 postProcessBeforeInitialization
Spring Bean 初始化后阶段:postProcessAfterInitialization