上文討論了Spring在進(jìn)行依賴注入的時(shí)候嫩舟,如何查找一個(gè)bean的依賴屬性氢烘,本文則討論在進(jìn)行依賴屬性的查找之前,進(jìn)行依賴查找之前的處理流程
在Spring容器中家厌,有兩個(gè)重要的內(nèi)置bean后置處理器威始,它們是AutowiredAnnotationBeanPostProcessor
和CommonAnnotationBeanPostProcessor
AutowiredAnnotationBeanPostProcessor
完成了對(duì)標(biāo)注@Autowired
、@Value
像街、@Inject
屬性的注入
CommonAnnotationBeanPostProcessor
完成了對(duì)JSR-250相關(guān)注解屬性的注入黎棠,如@WebServiceRef
、@EJB
镰绎、@Resource
脓斩,同時(shí),它也完成了一部分bean生命周期方法的處理畴栖,即@PostConstruct
随静、@PreDestroy
方法的回調(diào)
二者的功能類似,下面以AutowiredAnnotationBeanPostProcessor
進(jìn)行講解
AutowiredAnnotationBeanPostProcessor
實(shí)現(xiàn)了MergedBeanDefinitionPostProcessor
接口的postProcessMergedBeanDefinition
方法
public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
// 緩存bean的注入屬性元數(shù)據(jù)
private final Map<String, InjectionMetadata> injectionMetadataCache = new ConcurrentHashMap<>(256);
// ...
/**
* 解析當(dāng)前bean需要注入的屬性信息吗讶,生成一個(gè)注入屬性元數(shù)據(jù)InjectionMetadata
*/
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
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);
}
// 解析當(dāng)前類要注入的屬性的元數(shù)據(jù)
metadata = buildAutowiringMetadata(clazz);
// 緩存當(dāng)前類要注入屬性的元數(shù)據(jù)信息
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
// ...
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do { // 循環(huán)操作
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
// 解析標(biāo)注了注解的屬性
ReflectionUtils.doWithLocalFields(targetClass, field -> {
// 判斷是否標(biāo)注了相關(guān)注解信息
MergedAnnotation<?> ann = findAutowiredAnnotation(field);
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {
return; // 可見燎猛,static屬性是不會(huì)注入的
}
boolean required = determineRequiredStatus(ann);
currElements.add(new AutowiredFieldElement(field, required));
}
});
// 解析標(biāo)注了注解的方法
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static methods: " + method);
}
return;
}
if (method.getParameterCount() == 0) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation should only be used on methods with parameters: " +
method);
}
}
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
// 加到列表的頭部,注意照皆,由于每次都放置在隊(duì)列頭部
// 而解析從子類遞進(jìn)到父類重绷,則父類的數(shù)據(jù)會(huì)在前部
elements.addAll(0, currElements);
// 獲取父類信息,準(zhǔn)備開始下一次循環(huán)
targetClass = targetClass.getSuperclass();
} while (targetClass != null && targetClass != Object.class);
return InjectionMetadata.forElements(elements, clazz);
}
// 判斷是否標(biāo)注了相關(guān)注解
@Nullable
private MergedAnnotation<?> findAutowiredAnnotation(AccessibleObject ao) {
MergedAnnotations annotations = MergedAnnotations.from(ao);
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
MergedAnnotation<?> annotation = annotations.get(type);
if (annotation.isPresent()) {
return annotation;
}
}
return null;
}
}
到此一個(gè)bean的依賴屬性元數(shù)據(jù)被解析完畢膜毁,并緩存了起來(lái)昭卓,以上的步驟發(fā)生在實(shí)例化bean之后,屬性填充之前瘟滨,接著便是對(duì)這個(gè)實(shí)例化完畢的bean進(jìn)行屬性填充
AutowiredAnnotationBeanPostProcessor
同樣實(shí)現(xiàn)了InstantiationAwareBeanPostProcessor
接口的postProcessProperties
方法候醒,該方法用來(lái)對(duì)屬性進(jìn)行填充
public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
// 緩存bean的注入屬性元數(shù)據(jù)
private final Map<String, InjectionMetadata> injectionMetadataCache = new ConcurrentHashMap<>(256);
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// 獲取前面解析完畢的依賴屬性元數(shù)據(jù)
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
// 開始注入屬性
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;
}
}
public class InjectionMetadata {
// ...
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) {
// 通過(guò)循環(huán),依次將屬性注入目標(biāo)bean
element.inject(target, beanName, pvs);
}
}
}
}
在AutowiredAnnotationBeanPostProcessor
存在兩個(gè)內(nèi)部類AutowiredFieldElement
杂瘸、AutowiredMethodElement
倒淫,此處使用字段注入舉例
private class AutowiredFieldElement extends InjectionMetadata.InjectedElement {
// ...
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
// ...
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 {
// 這里就是上文依賴查找的調(diào)用發(fā)起的地方
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
} catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
// ...
if (value != null) {
// 最后如果獲取到的屬性bean不為null,將其注入到目標(biāo)bean中
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
}
參考圖: