一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情
日积月累,水滴石穿 😄
前言
前面几篇已经分析完了 Bean 是如何被创建出来的,那本篇就来分析 Spring 是如何知道 Bean 中的哪些属性是需要被注入的!
该方法位于 AbstractAutowireCapableBeanFactory
类。相信各位看到这段代码应该不会陌生了吧!执行 BeanPostProcessors
。如果不知道 BeanPostProcessors
有什么作用,如何使用,可以先去看看小杰的另外一篇文章:Spring源码-BeanPostProcessor
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);
}
}
}
这里会执行所有实现了MergedBeanDefinitionPostProcessor
接口的 BeanPostProcessor
。
可以看到实现了 MergedBeanDefinitionPostProcessor
接口的类还是挺多的。分别有以下实现:
- AutowiredAnnotationBeanPostProcessor:解析
Autowired
、Value
、Inject
注解。 - ScheduledAnnotationBeanPostProcessor:解析
Scheduled
注解。 - InitDestroyAnnotationBeanPostProcessor:解析
PreDestroy
、PostConstruct
注解。 - JmsListenerAnnotationBeanPostProcessor:解析
JmsListener
注解。 - PersistenceAnnotationBeanPostProcessor:解析
@PersistenceUnit
和@PersistenceContext
注解。 - CommonAnnotationBeanPostProcessor:解析
@Resource
、@WebServiceRef
、@EJB
注解。并且该类继承了InitDestroyAnnotationBeanPostProcessor
。
本篇将介绍 AutowiredAnnotationBeanPostProcessor
和CommonAnnotationBeanPostProcessor
这两个BeanPostProcessor
。
AutowiredAnnotationBeanPostProcessor
在所有的实现类中,选择AutowiredAnnotationBeanPostProcessor
类。先来看看AutowiredAnnotationBeanPostProcessor
类的继承图。
既然要解析这Autowired
、Value
、Inject
三个注解,那么在AutowiredAnnotationBeanPostProcessor
类中肯定要有这三个注解的相关代码。
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()
));
logger.trace(
"JSR-330 'javax.inject.Inject' annotation found and supported for autowiring"
);
}
catch(ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
}
可以看到这是一个无参构造方法,往 autowiredAnnotationTypes
属性中添加值。后面逻辑肯定会用到这个属性,判断当前类中是否包含 autowiredAnnotationTypes
属性的值。
好的,下面进入到正题,看看是如何去寻找注入点的。
方法传入三个入参,分别如下:
- beanDefinition:当前 bean 的定义
- beanType:实例对象的类型
- beanName:bean 名称
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition,
Class <? > beanType, String beanName) {
// 获取beanType中的注入点
InjectionMetadata metadata = findAutowiringMetadata(beanName,
beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
重点看一下 findAutowiringMetadata
方法。
private InjectionMetadata findAutowiringMetadata(String beanName,
Class <? > clazz, @Nullable PropertyValues pvs) {
// 如果当前 beanName 为null,那就选择class对象的名称
String cacheKey = (StringUtils.hasLength(beanName) ? beanName :
clazz.getName());
// 从缓存中获取
InjectionMetadata metadata = this.injectionMetadataCache.get(
cacheKey);
//如果缓存中有,不需要再次解析
//needsRefresh = true 需要解析
if(InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized(this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if(InjectionMetadata.needsRefresh(metadata, clazz)) {
if(metadata != null) {
metadata.clear(pvs);
}
// 寻找当前clazz中的注入点,把所有注入点整合成为一个InjectionMetadata对象
metadata = buildAutowiringMetadata(clazz);
// 添加到缓存中
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
调试进入 buildAutowiringMetadata
方法:
private InjectionMetadata buildAutowiringMetadata(final Class <? >
clazz) {
// 判断是不是候选者类,
//1、先判断注解的全限名称是否以"java."开头,如果是则返回true,否则进行第二步(如果类名的全路径是 java.xx.xx,启动的时候就会报错的)
//2、判断类的名称是否以"java."开头 或者 clazz的类型为 org.springframework.core.Ordered.class,如果是返回 false
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 <> ();
// 遍历属性,看是否有@Autowired,@Value,@Inject注解
ReflectionUtils.doWithLocalFields(targetClass, field - > {
//
MergedAnnotation <?> ann = findAutowiredAnnotation(field); >1
// 如果存在@Autowired,@Value,@Inject注解其中一个
if(ann != null) {
// 如果字段是static的,则直接进行返回,不进行注入
if(Modifier.isStatic(field.getModifiers())) {
if(logger.isInfoEnabled()) {
logger.info(
"Autowired annotation is not supported on static fields: " +
field);
}
return;
}
// 是否required
boolean required = determineRequiredStatus(ann);
// 生成一个注入点AutowiredFieldElement
currElements.add(new AutowiredFieldElement(field,
required));
}
});
// 遍历方法,看是否有@Autowired,@Value,@Inject注解
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;
}
// 方法参数个数为0,打印日志提示
if(method.getParameterCount() == 0) {
if(logger.isInfoEnabled()) {
logger.info(
"Autowired annotation should only be used on methods with parameters: " +
method);
}
}
boolean required = determineRequiredStatus(ann);
// 根据方法找出对应的属性描述 可能为 null(PropertyDescriptor下篇会将到)
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(
bridgedMethod, clazz);
currElements.add(new AutowiredMethodElement(method,
required, pd));
}
});
// 所有能够注入的属性集合
elements.addAll(0, currElements);
// 获得当前类的父类(当前类可能是一个代理类)
targetClass = targetClass.getSuperclass();
}
// 当前类不等于 null 并且当前类不是Object 则继续遍历
while (targetClass != null && targetClass != Object.class);
// 构建 InjectionMetadata 对象
return InjectionMetadata.forElements(elements, clazz);
}
看一下标记点>1
findAutowiredAnnotation
方法。
@Nullable
private MergedAnnotation <? > findAutowiredAnnotation(
AccessibleObject ao) {
// 查找当前字段或者方法上是否存在@Autowired,@Value,@Inject注解,并将之方法,可能会返回多个
//因为可以这么写:
//@Autowired
//@Value("sss")
//private BB b;
MergedAnnotations annotations = MergedAnnotations.from(ao);
// autowiredAnnotationTypes是一个LinkedHashSet,所以会按顺序去判断当前字段中是否有Autowired注解,如果有则返回
// 如果没有Autowired注解,那么则判断是否有Value注解,再判断是否有Inject注解
for(Class<? extends Annotation> type: this.autowiredAnnotationTypes) {
MergedAnnotation <?> annotation = annotations.get(type);
if(annotation.isPresent()) {
return annotation;
}
}
return null;
}
方法中的逻辑还是挺简单的。
- 1、根据传入的
Class
类型,先去判断是不是候选者类,如果类名是以"java."开头或者Class
的类型为org.springframework.core.Ordered.class
就不是候选者类。 - 2、开启 do、while 循环。
- 3、获得当前类的所有属性(包括public、private和proteced),遍历每个属性上是否包含
@Autowired,@Value,@Inject
注解,如果属性上存在注解,则判断当前属性是否是static
的,如果字段是static
的,则直接进行返回,不进行记录,代表当前属性不能进行注入。如果不是static
的,生成一个注入点AutowiredFieldElement
添加到currElements
中。 - 4、获得当前类的所有方法(包括private、protected、public),遍历每个方法上是否包含
@Autowired,@Value,@Inject
注解,如果方法上存在注解,则判断当前方法是否是static
的,如果方法是static
的,则直接进行返回,不进行记录。如果当前方法不是static
的,根据方法找出对应的属性,生成一个注入点AutowiredMethodElement
添加到currElements
中。
实例
测试 isCandidateClass
方,判断是不是候选者类。
- CC注解
package java;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({
ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER,
ElementType.ANNOTATION_TYPE
})
@Retention(RetentionPolicy.RUNTIME)
public@ interface CC {}
- 启动类
public static void main(String[] args) {
Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<>(4);
// autowiredAnnotationTypes.add(Autowired.class);
// autowiredAnnotationTypes.add(Value.class);
autowiredAnnotationTypes.add(CC.class);
boolean candidateClass = AnnotationUtils.isCandidateClass(CC.class, autowiredAnnotationTypes);
System.out.println("结果 = " + candidateClass);
}
结果 = true
CommonAnnotationBeanPostProcessor
AutowiredAnnotationBeanPostProcessor
的注入点解析已经完成了,小杰带各位小伙伴再来看看CommonAnnotationBeanPostProcessor
的注入点解析。还是老套路,既然要解析这WebServiceRef
、EJB
、Resource
三个注解,那么在CommonAnnotationBeanPostProcessor
类中肯定要有这三个注解的相关代码。
static {
try {
@SuppressWarnings("unchecked")
Class<? extends Annotation> clazz = (Class<? extends Annotation>)
ClassUtils.forName("javax.xml.ws.WebServiceRef",
CommonAnnotationBeanPostProcessor.class.getClassLoader());
webServiceRefClass = clazz;
}
catch(ClassNotFoundException ex) {
webServiceRefClass = null;
}
try {
@SuppressWarnings("unchecked")
Class <? extends Annotation> clazz = (Class <? extends Annotation>)
ClassUtils.forName("javax.ejb.EJB",
CommonAnnotationBeanPostProcessor.class.getClassLoader());
ejbRefClass = clazz;
}
catch(ClassNotFoundException ex) {
ejbRefClass = null;
}
resourceAnnotationTypes.add(Resource.class);
if(webServiceRefClass != null) {
resourceAnnotationTypes.add(webServiceRefClass);
}
if(ejbRefClass != null) {
resourceAnnotationTypes.add(ejbRefClass);
}
}
这次不是在无参构造方法中进行初始化了,是放在静态代码块中,向resourceAnnotationTypes
属性中添加值。
那再来看看无参构造方法。
public CommonAnnotationBeanPostProcessor() {
setOrder(Ordered.LOWEST_PRECEDENCE - 3);
setInitAnnotationType(PostConstruct.class);
setDestroyAnnotationType(PreDestroy.class);
ignoreResourceType("javax.xml.ws.WebServiceContext");
}
前面三个方法是调用父类InitDestroyAnnotationBeanPostProcessor
中的方法,进行属性赋值。
public void setOrder(int order) {
this.order = order;
}
public void setInitAnnotationType(Class<? extends Annotation> initAnnotationType) {
this.initAnnotationType = initAnnotationType;
}
public void setDestroyAnnotationType(Class<? extends Annotation> destroyAnnotationType) {
this.destroyAnnotationType = destroyAnnotationType;
}
最后一个方法是给本类属性赋值。
//忽略的资源类型
private final Set<String> ignoredResourceTypes = new HashSet<>(1);
public void ignoreResourceType(String resourceType) {
Assert.notNull(resourceType, "Ignored resource type must not be null");
this.ignoredResourceTypes.add(resourceType);
}
OK,了解了一下前置知识,进入到主流程中。
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition,
Class <? > beanType, String beanName) {
//调用父类 InitDestroyAnnotationBeanPostProcessor
super.postProcessMergedBeanDefinition(beanDefinition, beanType,
beanName);
InjectionMetadata metadata = findResourceMetadata(beanName,
beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
首先会调用父类的postProcessMergedBeanDefinition
方法,然后调用本类findResourceMetadata
方法。
上面我们讲到CommonAnnoatationBeanPostProcessor
的父类是InitDestoryAnnoatationBeanPostProcessor
,在InitDestoryAnnoatationBeanPostProcessor
类中postProcessMergedBeanDefinition
方法会解析和初始化(@PostConstruct
)和销毁(@PreDestory
)注解并缓存到lifecycleMetadataCache
中。
父类
那我先来看一下 InitDestoryAnnoatationBeanPostProcessor
类中的 postProcessMergedBeanDefinition
方法。
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition,
Class <?> beanType, String beanName) {
LifecycleMetadata metadata = findLifecycleMetadata(beanType);
metadata.checkConfigMembers(beanDefinition);
}
然后再进入findLifecycleMetadata
方法,传入实例对象的类型。
private LifecycleMetadata findLifecycleMetadata(Class <?> clazz) {
//lifecycleMetadataCache属性是一个 Map clazz 为key LifecycleMetadata 为值
if(this.lifecycleMetadataCache == null) {
// Happens after deserialization, during destruction...
return buildLifecycleMetadata(clazz);
}
// Quick check on the concurrent map first, with minimal locking.
LifecycleMetadata metadata = this.lifecycleMetadataCache.get(
clazz);
if(metadata == null) {
synchronized(this.lifecycleMetadataCache) {
metadata = this.lifecycleMetadataCache.get(clazz);
if(metadata == null) {
metadata = buildLifecycleMetadata(clazz);
//将结果缓存在lifecycleMetadataCache中
this.lifecycleMetadataCache.put(clazz, metadata);
}
return metadata;
}
}
return metadata;
}
关注buildLifecycleMetadata
方法,其他逻辑就是判断缓存里面有没有。
private LifecycleMetadata buildLifecycleMetadata(final Class <? >
clazz) {
//判断是不是候选者,逻辑与一致,不在哔哔了
// initAnnotationType 存的是 PostConstruct
// destroyAnnotationType 存的是 PreDestroy
if(!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType,
this.destroyAnnotationType))) {
return this.emptyLifecycleMetadata;
}
List <LifecycleElement> initMethods = new ArrayList <> ();
List <LifecycleElement> destroyMethods = new ArrayList <> ();
Class <?> targetClass = clazz;
do {
final List <LifecycleElement> currInitMethods = new ArrayList<>();
final List <LifecycleElement> currDestroyMethods = new ArrayList<>();
//遍历当前类方法,看是否有@PostConstruct,@PreDestroy注解
ReflectionUtils.doWithLocalMethods(targetClass, method - > {
//当前方法上包含 @PostConstruct 注解
if(this.initAnnotationType != null && method.isAnnotationPresent(
this.initAnnotationType)) {
//构建LifecycleElement对象
LifecycleElement element = new LifecycleElement(method);
//将 LifecycleElement 对象添加到集合中
currInitMethods.add(element);
if(logger.isTraceEnabled()) {
logger.trace("Found init method on class [" + clazz.getName() +
"]: " + method);
}
}
//当前方法上包含 @PreDestroy 注解
if(this.destroyAnnotationType != null && method.isAnnotationPresent(
this.destroyAnnotationType)) {
currDestroyMethods.add(new LifecycleElement(method));
if(logger.isTraceEnabled()) {
logger.trace("Found destroy method on class [" +
clazz.getName() + "]: " + method);
}
}
});
initMethods.addAll(0, currInitMethods);
destroyMethods.addAll(currDestroyMethods);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
return(initMethods.isEmpty() && destroyMethods.isEmpty() ? this.emptyLifecycleMetadata :
new LifecycleMetadata(clazz, initMethods, destroyMethods));
}
相比较于AutowiredAnnotationBeanPostProcessor
中的逻辑简单了许多,遍历所有的方法,判断每个方法上是否标注了 @PostConstruct
,@PreDestroy
注解(可以得出这两个注解只能写在方法上),分别存入initMethods
、destroyMethods
两个集合中,并将结果缓存在lifecycleMetadataCache
中。
本类
看看本类的findResourceMetadata
方法。
private InjectionMetadata findResourceMetadata(String beanName,
final Class <?> clazz, @Nullable PropertyValues pvs) {
// 如果当前 beanName 为null,那就选择class对象的名称
String cacheKey = (StringUtils.hasLength(beanName) ? beanName :
clazz.getName());
// 从缓存中获取
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 = buildResourceMetadata(clazz);
//将结果缓存起来
//injectionMetadataCache 是一个Map
//key 为 beanName
//value 为 InjectionMetadata 对象
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
额!关注buildResourceMetadata
方法。
private InjectionMetadata buildResourceMetadata(final Class <?>
clazz) {
//不哔哔
if(!AnnotationUtils.isCandidateClass(clazz,
resourceAnnotationTypes)) {
return InjectionMetadata.EMPTY;
}
List <InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class <?> targetClass = clazz;
do {
final List <InjectionMetadata.InjectedElement> currElements =
new ArrayList <> ();
//遍历所有字段属性,看是否有@WebServiceRef,@EJB,@Resource注解
ReflectionUtils.doWithLocalFields(targetClass, field - > {
//当前属性上包含 @WebServiceRef 注解
if(webServiceRefClass != null && field.isAnnotationPresent(
webServiceRefClass)) {
//是否是静态属性 如果是抛出异常
if(Modifier.isStatic(field.getModifiers())) {
throw new IllegalStateException(
"@WebServiceRef annotation is not supported on static fields"
);
}
//构建一个 WebServiceRefElement 对象添加到集合中
currElements.add(new WebServiceRefElement(field, field,
null));
}
//当前属性上包含 @EJB 注解
else if(ejbRefClass != null && field.isAnnotationPresent(
ejbRefClass)) {
//是否是静态属性 如果是抛出异常
if(Modifier.isStatic(field.getModifiers())) {
throw new IllegalStateException(
"@EJB annotation is not supported on static fields"
);
}
//构建一个 EjbRefElement 对象添加到集合中
currElements.add(new EjbRefElement(field, field, null));
}
//当前属性上包含 @Resource 注解
else if(field.isAnnotationPresent(Resource.class)) {
//是否是静态属性 如果是抛出异常
if(Modifier.isStatic(field.getModifiers())) {
throw new IllegalStateException(
"@Resource annotation is not supported on static fields"
);
}
//当前属性类型的名称不能包含 javax.xml.ws.WebServiceContext
//也就是说你不能使用以下写法:
//@Resource
//private WebServiceContext wsContext;
if(!this.ignoredResourceTypes.contains(field.getType().getName())) {
//构建一个 ResourceElement 对象添加到集合中
currElements.add(new ResourceElement(field, field,
null));
}
}
});
//遍历当前类所有方法,看是否有@WebServiceRef,@EJB,@Resource注解
ReflectionUtils.doWithLocalMethods(targetClass, method - > {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(
method);
if(!BridgeMethodResolver.isVisibilityBridgeMethodPair(
method, bridgedMethod)) {
return;
}
if(method.equals(ClassUtils.getMostSpecificMethod(method,
clazz))) {
//当前方法上包含 @WebServiceRef 注解
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);
//构建 WebServiceRefElement 对象 添加到 currElements 集合中
currElements.add(new WebServiceRefElement(method,
bridgedMethod, pd));
}
//当前方法上包含 @EJB 注解
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);
//构建 EjbRefElement 对象 添加到 currElements 集合中
currElements.add(new EjbRefElement(method,
bridgedMethod, pd));
}
//当前方法上包含 @Resource 注解
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();
// 参数类型长度只能是 1,也就是方法参数个数只能是一个,否则抛出异常
if(paramTypes.length != 1) {
throw new IllegalStateException(
"@Resource annotation requires a single-arg method: " +
method);
}
//当前方法参数类型的名称不能包含 javax.xml.ws.WebServiceContext
if(!this.ignoredResourceTypes.contains(paramTypes[0].getName())) {
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(
bridgedMethod, clazz);
//构建 ResourceElement 对象 添加到 currElements 集合中
currElements.add(new ResourceElement(method,
bridgedMethod, pd));
}
}
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
return InjectionMetadata.forElements(elements, clazz);
}
大体逻辑都差不多的,就是解析属性或者方法上有没有注解,属性、方法是不是静态的。
总结
到此呢,AutowiredAnnotationBeanPostProcessor
和CommonAnnotationBeanPostProcessor
的注入点分析都已经完成啦~。都会将值缓存起来,AutowiredAnnotationBeanPostProcessor
将值缓存在AutowiredAnnotationBeanPostProcessor
的属性injectionMetadataCache
中,CommonAnnotationBeanPostProcessor
将值缓存在CommonAnnotationBeanPostProcessor
类的属性injectionMetadataCache
中。InitDestoryAnnoatationBeanPostProcessor
将值缓存在InitDestoryAnnoatationBeanPostProcessor
类中的属性lifecycleMetadataCache
中。
之后的博文会分析如何使用AutowiredAnnotationBeanPostProcessor
、CommonAnnotationBeanPostProcessor
缓存中的信息,这两者的信息是在postProcessPerties
方法中被使用。
至于InitDestoryAnnoatationBeanPostProcessor
的缓存信息,PostConstruct
是在 postProcessBeforeInitialization
初始化前方法中被执行,PreDestroy
是在postProcessBeforeDestruction
销毁前方法中被执行。