回顾
1.4.2 createBean(beanName, mbd, args)
我们讲获取 Bean 实例的过程
1.4.2.1 createBeanInstance(beanName, mbd, args)
通过构造函数创建 Bean 实例。
构造函数上如果有 @Autowired,会先将引用类型的入参对象优先实例化。
但此时的 Bean 实例里的属性上、非构造方法上如果有 @Autowired,还没有进行依赖注入。
1.4.2.2 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)
请求 CommonAnnotationBeanPostProcessor 和 AutowiredAnnotationBeanPostProcessor,
扫描方法上是否有@PostConstruct @PreDestroy注解,有注解的封装成 LifecycleMetadata
扫描方法和属性上是否有@Resource注解
扫描方法和属性上是否有@Autowired @Value注解
对这些有注解的方法和属性封装成 InjectionMetadata
本节重点
本节的方法 populateBean 实现了对有 @Autowired 和 @Resource 的属性和非构造方法进行依赖注入。
无论是 CommonAnnotationBeanPostProcessor 还是 AutowiredAnnotationBeanPostProcessor,类的内部都有一个 map 来存储 InjectionMetadata
private final transient Map<String, InjectionMetadata> injectionMetadataCache = new ConcurrentHashMap<>(256);
populateBean 这个方法正是从这个缓存里拿到的 InjectionMetadata,进而通过 InjectionMetadata 里的信息来进行依赖注入。当然,注入的实例会进行优先实例化。
跟源码
类 AbstractAutowireCapableBeanFactory
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.
boolean continueWithPropertyPopulation = true;
//这里很有意思,写接口可以让所有类都不能依赖注入
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
//是否需要DI,依赖注入
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
//不看
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
//重要程度:5
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//依赖注入过程,@Autowired @Resource 的支持
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
//老版本用这个完成依赖注入过程,@Autowired的支持
pvsToUse = ibp.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);
}
//重要程度:0 老版本用<property name="username" value="Jack"/>
//标签做依赖注入的代码实现,复杂且无用
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
跟 postProcessProperties:
类 InstantiationAwareBeanPostProcessor
这两种差不多,我们先看 CommonAnnotationBeanPostProcessor:
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
//这个方法 1.4.2.2 已经看过了,先从缓存里找,没有就去创建
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;
}
跟 inject:
类 InjectionMetadata.InjectedElement
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()) {
for (InjectedElement element : elementsToIterate) {
if (logger.isTraceEnabled()) {
logger.trace("Processing injected element of bean '" + beanName + "': " + element);
}
if(element.isField) {
Field field = (Field)element.member;
}
element.inject(target, beanName, pvs);
}
}
}
跟 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);
//这里面有 getBean 操作
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();
}
}
}
对于 AutowiredAnnotationBeanPostProcessor 也是调用 metadata.inject(bean, beanName, pvs),但 AutowiredAnnotationBeanPostProcessor 里面有2个私有类重写了这个方法:
我们只看 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) {
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 {
//这里面有getBean的操作,拿到依赖的实例
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {
if (!this.cached) {
if (value != null || this.required) {
this.cachedFieldValue = desc;
registerDependentBeans(beanName, autowiredBeanNames);
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;
}
}
}
if (value != null) {
ReflectionUtils.makeAccessible(field);
//依赖注入
field.set(bean, value);
}
}