随笔分类
依赖注入 populateBean
populateBean
/**
* 这里来完成依赖注入
* 总结:
* 1.执行实例化之后对应的后置处理器 postProcessAfterInstantiation, 根据返回值可以来控制是否继续进行属性的填充
* 2.根据注入类型 (byName / byType), 提取依赖的 bean,并统一存入 PropertyValues中
* 3.应用 后置处理器InstantiationAwareBeanPostProcessor的 postProcessorProperties方法,
* 在给定的 BeanDefinition属性设置到 bean里面之前,可以通过 postProcessProperties来进行属性修改
* 4.将所有 PropertyValues中的属性填充至 BeanWrapper中
*/
@SuppressWarnings("deprecation") // for postProcessPropertyValues
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.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
/** 这里其实又是一个后置处理器的一个调用点 postProcessAfterInstantiation 实例化之后的后置处理器 **/
/** 这里执行的后置处理器是在 "依赖注入"之前 **/
/** InstantiationAwareBeanPostProcessor 最后一次机会在属性设置值前来改变 bean **/
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
// postProcessAfterInstantiation 返回值决定了后续是否需要进行依赖注入的处理
// 后置处理器发出了停止填充的命令则终止后续的执行
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
/** 后面的逻辑就是要来处理依赖数据... 依赖注入的主逻辑 **/
// 这里获取的数据实际上就是:<property name="carName" value="良夜跑车安全第一舒舒适第二速度第三" />
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
/**
* 这里来来获取的主要是 Autowired的模式: byType? byName? default? constructor?
* 这里主要关注的便是 byType 和 byName两种类型
*/
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
// true -> bd AutowireMode是 AUTOWIRE_BY_NAME 或者 AUTOWIRE_BY_TYPE
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
// 包装成 MutablePropertyValues
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
/** 不同 mode走不同的逻辑路线 **/
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
/**
* byName会做什么?
* 根据字段名称,去查找依赖 bean,然后完成注入
*/
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 **/
pvs = newPvs;
}
// 表示当前是否拥有 InstantiationAware系列的后处理器,需要调用
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
// 先跳过...
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
/** 我们来考虑 pvs是有值的情况 **/
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
/** 后置处理器的调用点:调用 InstantiationAwareBeanPostProcessor的 postProcessorProperties方法 **/
/** 在给定的 BeanDefinition属性设置到 bean里面之前,可以通过 postProcessProperties来进行属性修改 **/
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
/** 将存放在 AutowiredAnnotationBeanPostProcessor 缓存中的元数据转化并存放到 PropertyValue中去**/
/** 典型应用:@Autowired 注解的注入 **/
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
/** 来到这说明已经完成了对所有依赖注入属性的获取 **/
if (pvs != null) {
/** 将依赖注入合并后的 pvs注入到真实的 bean实例中去 **/
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
postProcessAfterInstantiation
/**
* 通过构造函数或工厂方法在实例化 bean之后但发生在 Spring属性填充(依赖注入 / 自动装配) 之前的操作
* 这是 Spring的自动装配开始之前, 在给定的 bean实例上执行 "自定义字段注入"的理想回调
* 默认实现返回 true, true -> 表示后续仍然需要进行 "依赖注入"的处理
* false -> 表示后续不需要再去进行 "依赖注入"的处理
* 最后一次机会在属性设置值前来改变 bean
*/
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
autowireByName
根据名称来进行注入
byName:根据被注入属性的名称作为 Bean名称作为依赖查找,并将对象设置到该属性
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
// bean实例中有该字段,且有该字段对应的setter方法,但是配置文件中并没有去配置 Property属性
// 寻找 bw中需要依赖注入的属性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
/** 遍历查找到的 propertyNames, 进行依赖注入 **/
for (String propertyName : propertyNames) {
// 条件成立 -> 说明当前 beanFactory中存在当前 propertyName的bean实例 或者说是 存在对应 name 的 BeanDefinition
if (containsBean(propertyName)) {
// 拿到 propertyName对应的 bean实例
Object bean = getBean(propertyName);
// 追加一个 property
pvs.add(propertyName, 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");
}
}
}
}
unsatisfiedNonSimpleProperties
protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
Set<String> result = new TreeSet<>();
// 这里是去拿到配置文件中配置的 Property信息
PropertyValues pvs = mbd.getPropertyValues();
// 这里是去拿到 mbd中所有的 字段信息
PropertyDescriptor[] pds = bw.getPropertyDescriptors();
// 条件1:true -> 当前字段有对应的 setter方法
// 条件2:true -> 当前字段并不在 "忽略自动注入列表"中
// 条件3:true -> 当前字段不在 xml 或者 其它方式的配置中配置过,即 bd并不存在对应的 Property
// 条件4:true -> 当前字段不是基本数据类型 (个人理解:这里实际上想要拿到的应该是在 property中对应别的 bean实例的情况)
for (PropertyDescriptor pd : pds) {
if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
!BeanUtils.isSimpleProperty(pd.getPropertyType())) {
result.add(pd.getName());
}
}
return StringUtils.toStringArray(result);
}
autowireByType
byType:根据被注入属性的类型作为依赖类型进行依赖查找,并且将该对象设置到该属性
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);
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.
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.
boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
// 依赖描述信息对象
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
/** 根据依赖描述信息查找到 描述对象, 或者说容器中没有对应的实例的话,但是有该类型的 bd的话,也会调用 getBean(Type) 获取到对象 **/
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
// 这里也是进行添加注册
pvs.add(propertyName, autowiredArgument);
}
for (String autowiredBeanName : autowiredBeanNames) {
registerDependentBean(autowiredBeanName, beanName);
if (logger.isTraceEnabled()) {
logger.trace("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);
}
}
}
postProcessProperties
在给定的 BeanDefinition属性设置到 bean里面之前,可以通过 postProcessProperties来进行属性修改
# AutowiredAnnotationBeanPostProcessor
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
/** 包装着当前 bd 需要注入的注解信息集合 @Autowired、@Value、@Inject信息元数据 **/
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
/** 将注解信息解析后注入到 pvs中 **/
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;
}
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()) {
/** 迭代处理当前 bean需要的注解信息 **/
for (InjectedElement element : elementsToIterate) {
/** 对当前迭代到的注解信息进行注入 **/
element.inject(target, beanName, pvs);
}
}
}
# AutowiredFieldElement
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
if (this.cached) {
try {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
catch (NoSuchBeanDefinitionException ex) {
// Unexpected removal of target bean for cached argument -> re-resolve
value = resolveFieldValue(field, bean, beanName);
}
}
/** 我们主要来分析这个路线 **/
else {
value = resolveFieldValue(field, bean, beanName);
}
/** 条件成立, 说明已经在 resolveFieldValue方法中根据依赖信息到容器中拿到了 依赖对象**/
if (value != null) {
/** 使用反射技术将当前 value赋值到当前 bean的 field字段中去... 完成依赖注入 **/
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
resolvedFieldValue
@Nullable
private Object resolveFieldValue(Field field, Object bean, @Nullable String beanName) {
// 根据注解描述的字段和required信息 创建出来依赖信息描述对象
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();
Object value;
try {
// 解析出来真实的依赖对象
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {
if (!this.cached) {
Object cachedFieldValue = null;
if (value != null || this.required) {
cachedFieldValue = desc;
// 这里会去注册依赖关系
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
this.cachedFieldValue = cachedFieldValue;
this.cached = true;
}
}
return value;
}