Spring 5.x Source trip twenty-seven getBean Detailed twelve applyMergedBeanDefinitionPostProcessors two
- AutowiredAnnotationBeanPostProcessor的postProcessMergedBeanDefinition
- Looking automatic assembling metadata findAutowiringMetadata
- InjectionMetadata的checkConfigMembers
- ApplicationListenerDetector的postProcessMergedBeanDefinition
- to sum up
AutowiredAnnotationBeanPostProcessor的postProcessMergedBeanDefinition
Previous to say CommonAnnotationBeanPostProcessor
the treatment, processing over will turn to AutowiredAnnotationBeanPostProcessor
deal with the matter, we see it.
In fact, it is to look for Autowired
and Value
the methods and properties of annotations.
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
Looking automatic assembling metadata findAutowiringMetadata
And in front CommonAnnotationBeanPostProcessor
of findLifecycleMetadata
like it, go first to the cache, no longer created, are synchronized with dual detection.
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);
}
metadata = buildAutowiringMetadata(clazz);//构建自动创配的属性和方法元数据
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
Construction of automatic assembling metadata buildAutowiringMetadata
I would have to find Autowired
and Value
annotated properties and methods of the parent class also includes a custom, packaged AutowiredMethodElement
into the collection.
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
return InjectionMetadata.EMPTY;
}
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do {
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
ReflectionUtils.doWithLocalFields(targetClass, field -> {
MergedAnnotation<?> ann = findAutowiredAnnotation(field);
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {//Autowired注解不支持静态方法
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static fields: " + field);
}
return;
}
boolean required = determineRequiredStatus(ann);//查看是否是required的
currElements.add(new AutowiredFieldElement(field, required));
}
});
//处理桥接方法
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));
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
return InjectionMetadata.forElements(elements, clazz);
}
The processing attribute ReflectionUtils doWithLocalFields
Deal with all the attributes.
public static void doWithLocalFields(Class<?> clazz, FieldCallback fc) {
for (Field field : getDeclaredFields(clazz)) {
try {
fc.doWith(field);
}
catch (IllegalAccessException ex) {
throw new IllegalStateException("Not allowed to access field '" + field.getName() + "': " + ex);
}
}
}
The processing method ReflectionUtils doWithLocalMethods
To keep up with this type of approach is, on the approach Autowired
and Value
notes.
public static void doWithLocalMethods(Class<?> clazz, MethodCallback mc) {
Method[] methods = getDeclaredMethods(clazz, false);
for (Method method : methods) {
try {
mc.doWith(method);
}
catch (IllegalAccessException ex) {
throw new IllegalStateException("Not allowed to access method '" + method.getName() + "': " + ex);
}
}
}
FieldCallback的doWith
In fact, a lambda
expression processing, automatic assembly find the annotation, and if there is to remove non-stationary required
, then encapsulated AutowiredFieldElement
to the collection.
field -> {
MergedAnnotation<?> ann = findAutowiredAnnotation(field);
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {//Autowired注解不支持静态方法
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static fields: " + field);
}
return;
}
boolean required = determineRequiredStatus(ann);//查看是否是required的
currElements.add(new AutowiredFieldElement(field, required));
}
findAutowiredAnnotation
In fact, to see if there is Autowired
and Value
notes, any returns.
@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;
}
InjectionMetadata 的 forElements
Finally, depending on whether there have properties and methods Autowired
and Value
comments, there is no return InjectionMetadata.EMPTY
, some words on the package to InjectionMetadata
return.
public static InjectionMetadata forElements(Collection<InjectedElement> elements, Class<?> clazz) {
return (elements.isEmpty() ? InjectionMetadata.EMPTY : new InjectionMetadata(clazz, elements));
}
InjectionMetadata的checkConfigMembers
If there are annotated collection of properties and methods that will tell them to sign up to beanDefinition
the set externallyManagedConfigMembers
in.
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
Set<InjectedElement> checkedElements = new LinkedHashSet<>(this.injectedElements.size());
for (InjectedElement element : this.injectedElements) {
Member member = element.getMember();
if (!beanDefinition.isExternallyManagedConfigMember(member)) {
beanDefinition.registerExternallyManagedConfigMember(member);
checkedElements.add(element);
if (logger.isTraceEnabled()) {
logger.trace("Registered injected element on class [" + this.targetClass.getName() + "]: " + element);
}
}
}
this.checkedElements = checkedElements;
}
ApplicationListenerDetector的postProcessMergedBeanDefinition
The only record the name and whether it is mapping a single case.
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
this.singletonNames.put(beanName, beanDefinition.isSingleton());
}
to sum up
In fact, applyMergedBeanDefinitionPostProcessors
the main thing to do is to use the processor to automatically assemble information on the properties and methods recorded into bean
the definition, the time to fill in the back can be used, including the CommonAnnotationBeanPostProcessor
life-cycle approach and webService,ejb,Resource
notes as well as information AutowiredAnnotationBeanPostProcessor
of Autowired
and Value
notes information.
Well, here today, we hope to help study and understand, do not spray the Great God see, understand only their own learning, limited capacity, please excuse.