繼續(xù)回到doCreateBean方法,經(jīng)過createBeanInstance(beanName, mbd, args),Spring已經(jīng)為我們創(chuàng)建好Bean實(shí)例,只是此時Bean尚未成熟,不能暴露給外部使用
再來到applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName),在這里Spring可以掃描每個類中那些屬性需要自動注入
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd,
final @Nullable Object[] args) throws BeanCreationException {
// ...
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 進(jìn)行一次后置處理器的處理,進(jìn)行掃描Bean類屬性是否使用了@Autowired等功能
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable ex) {
// ...
}
mbd.postProcessed = true;
}
}
// ...
return exposedObject;
}
/**
* 循環(huán)執(zhí)行MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
*/
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd,
Class<?> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
擴(kuò)展:以AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor應(yīng)用為例,簡述MergedBeanDefinitionPostProcessor應(yīng)用
AutowiredAnnotationBeanPostProcessor
public class AutowiredAnnotationBeanPostProcessor
extends InstantiationAwareBeanPostProcessorAdapter
implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
private final Map<String, InjectionMetadata> injectionMetadataCache
= new ConcurrentHashMap<>(256);
// ...
/**
* 在構(gòu)造器中添加當(dāng)前后置處理器可以處理的注解:@Autowired、@Value、@Inject
*/
public AutowiredAnnotationBeanPostProcessor() {
this.autowiredAnnotationTypes.add(Autowired.class);
this.autowiredAnnotationTypes.add(Value.class);
try {
this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
ClassUtils.forName("javax.inject.Inject",
AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
}
/**
* 通過postProcessMergedBeanDefinition查找當(dāng)前Bean需要注入的屬性
*/
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition,
Class<?> beanType, String beanName) {
// 查找當(dāng)前Bean定義中需要進(jìn)行Autowired操作的屬性
// 生成一個當(dāng)前Bean注入屬性元數(shù)據(jù)對象
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
// 將需要注入的屬性元數(shù)據(jù)保存到當(dāng)前BeanDefinition中
metadata.checkConfigMembers(beanDefinition);
}
/**
* 查找類中需要注入的屬性元數(shù)據(jù)
*/
private InjectionMetadata findAutowiringMetadata(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.
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);
}
// 構(gòu)造當(dāng)前BeanDefinition需要進(jìn)行注入的屬性元數(shù)據(jù)
metadata = buildAutowiringMetadata(clazz);
// 緩存處理過的類屬性注入元數(shù)據(jù)
// 當(dāng)前后置處理器會處理所有Spring容器管理Bean的注入屬性元數(shù)據(jù)
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
/**
* 實(shí)際查找類中需要注入的屬性元數(shù)據(jù)
*/
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<>();
Class<?> targetClass = clazz;
// 循環(huán)這個類的所有屬性
do {
final LinkedList<InjectionMetadata.InjectedElement> currElements
= new LinkedList<>();
ReflectionUtils.doWithLocalFields(targetClass, field -> {
// 尋找含有在autowiredAnnotationTypes注解列表里面的屬性:
// @Value、@Autowired、@Inject標(biāo)注的屬性
AnnotationAttributes ann = findAutowiredAnnotation(field);
if (ann != null) {
// 看到這里,就應(yīng)該明白為什么使用static修飾的屬性無法注入
// Spring并不將static屬性作為要自動注入的目標(biāo)?。。。?!
if (Modifier.isStatic(field.getModifiers())) {
return;
}
boolean required = determineRequiredStatus(ann);
// 增加一個需要自動注入的屬性
currElements.add(new AutowiredFieldElement(field, required));
}
});
// 尋找需要自動注入的方法
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver
.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
if (ann != null
&& method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
return;
}
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd
= BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
elements.addAll(0, currElements);
// 類似遞歸去尋找他父類的注入信息
targetClass = targetClass.getSuperclass();
} while (targetClass != null && targetClass != Object.class);
return new InjectionMetadata(clazz, elements);
}
// ...
}
CommonAnnotationBeanPostProcessor
省略和AutowiredAnnotationBeanPostProcessor類似的處理流程,直接看它是怎么處理需要自動注入的屬性的,主要關(guān)注代碼中field.isAnnotationPresent是否含有注解的判斷
private InjectionMetadata buildResourceMetadata(final Class<?> clazz) {
LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<>();
Class<?> targetClass = clazz;
do {
final LinkedList<InjectionMetadata.InjectedElement> currElements =
new LinkedList<>();
ReflectionUtils.doWithLocalFields(targetClass, field -> {
if (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) {
if (Modifier.isStatic(field.getModifiers())) {
throw new IllegalStateException(
"@WebServiceRef annotation is not supported on static fields");
}
currElements.add(new WebServiceRefElement(field, field, null));
} else if (ejbRefClass != null && field.isAnnotationPresent(ejbRefClass)) {
if (Modifier.isStatic(field.getModifiers())) {
throw new IllegalStateException(
"@EJB annotation is not supported on static fields");
}
currElements.add(new EjbRefElement(field, field, null));
} else if (field.isAnnotationPresent(Resource.class)) {
if (Modifier.isStatic(field.getModifiers())) {
throw new IllegalStateException(
"@Resource annotation is not supported on static fields");
}
if (!ignoredResourceTypes.contains(field.getType().getName())) {
currElements.add(new ResourceElement(field, field, null));
}
}
});
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
if (method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (webServiceRefClass != null
&& bridgedMethod.isAnnotationPresent(webServiceRefClass)) {
if (Modifier.isStatic(method.getModifiers())) {
throw new IllegalStateException(
"@WebServiceRef annotation is not supported on static methods");
}
if (method.getParameterCount() != 1) {
throw new IllegalStateException(
"@WebServiceRef annotation requires a single-arg method: "
+ method);
}
PropertyDescriptor pd
= BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new WebServiceRefElement(method, bridgedMethod, pd));
} else if (ejbRefClass != null
&& bridgedMethod.isAnnotationPresent(ejbRefClass)) {
if (Modifier.isStatic(method.getModifiers())) {
throw new IllegalStateException(
"@EJB annotation is not supported on static methods");
}
if (method.getParameterCount() != 1) {
throw new IllegalStateException(
"@EJB annotation requires a single-arg method: " + method);
}
PropertyDescriptor pd
= BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new EjbRefElement(method, bridgedMethod, pd));
} else if (bridgedMethod.isAnnotationPresent(Resource.class)) {
if (Modifier.isStatic(method.getModifiers())) {
throw new IllegalStateException(
"@Resource annotation is not supported on static methods");
}
Class<?>[] paramTypes = method.getParameterTypes();
if (paramTypes.length != 1) {
throw new IllegalStateException(
"@Resource annotation requires a single-arg method: " + method);
}
if (!ignoredResourceTypes.contains(paramTypes[0].getName())) {
PropertyDescriptor pd
= BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new ResourceElement(method, bridgedMethod, pd));
}
}
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
} while (targetClass != null && targetClass != Object.class);
return new InjectionMetadata(clazz, elements);
}
小結(jié)
AutowiredAnnotationBeanPostProcessor會掃描Bean的類中是否使用了@Autowired和@Value注解,掃描到的對象會封裝成一個InjectionMetadata對象,緩存到一個Map集合中,后續(xù)根據(jù)緩存信息進(jìn)行屬性填充;
CommonAnnotationBeanPostProcessor則會掃描Bean類中是否使用了@Resource等注解,同樣緩存起來等待后續(xù)進(jìn)行屬性填充。