上篇咱们聊到了bean实例的创建,按照流程图上面接下来应该进行属性填充了。这在里咱们思考一个问题,咱们@Autowired,@Value,@Resource,@PostConstruct,@PreDestroy是什么时候处理的呢,假如xml中配置了,注解也配置了,应该怎么处理呢?
- AutowiredAnnotationBeanPostProcessor 处理@Autowired和@Value注解bean定义信息
- CommonAnnotationBeanPostProcessor 处理@Resource、@PostConstruct、@PreDestroy注解的bean定义信息
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// 这里是为了解决循环依赖,提前把创建bean的工厂方法放到三级缓存
// 也就是如果需要代理会返回代理对象,如果不需要代理,返回前面创建的对象
//后面会单独了解循环依赖
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));//添加到三级缓存
}
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
// CommonAnnotationBeanPostProcessor 处理的注解(@PostConstruct、@PreDestroy、@Resource、WebServiceRef、EJB)
// AutowiredAnnotationBeanPostProcessor 处理的注解(@Autowired,@Value)
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
咱们这里先明确一个点,这里只是解析注解,并没有进行赋值 *** 作
MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition 执行bean定义信息合并咱们主要了解上面说的两个类
CommonAnnotationBeanPostProcessor.postProcessMergedBeanDefinition 解析注解信息并添加到缓存@Resource和Autowired很像
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
//解析@PostConstruct与@PreDestroy,并封装到Metadata中,把Metadata放到lifecycleMetadataCache
super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
//解析@Resource注解
InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
// 检查的作用就是看看外部有没有已经配置了,如果配置了丢弃掉注解的配置
metadata.checkConfigMembers(beanDefinition);
}
InitDestroyAnnotationBeanPostProcessor.postProcessMergedBeanDefinition 解析初始化和销毁方法
这里处理的是@PostConstruct和@PreDestroy
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
LifecycleMetadata metadata = findLifecycleMetadata(beanType);
metadata.checkConfigMembers(beanDefinition);
}
InitDestroyAnnotationBeanPostProcessor.findLifecycleMetadata查找返回注解元数据信息
// 获取@PostConstruct和@Destroy注解标注的方法,包括父类,然后放入缓存,方便下次获取
private LifecycleMetadata findLifecycleMetadata(Class<?> clazz) {
// 这里只是做了一次检查,buildLifecycleMetadata是咱们重点关注的方法
if (this.lifecycleMetadataCache == null) {
return buildLifecycleMetadata(clazz);
}
LifecycleMetadata metadata = this.lifecycleMetadataCache.get(clazz);
if (metadata == null) {
synchronized (this.lifecycleMetadataCache) {
metadata = this.lifecycleMetadataCache.get(clazz);
if (metadata == null) {
// 构建元数据
metadata = buildLifecycleMetadata(clazz);
//这里大家可以想一个问题,为什么使用ConcurrentHashMap呢?
//这个过程可能会涉及到并发修改,也有可能会改变目标类,哪种情况下会被更改呢?
//为什么要修改目标类对象呢?
this.lifecycleMetadataCache.put(clazz, metadata);
}
return metadata;
}
}
return metadata;
}
InitDestroyAnnotationBeanPostProcessor.buildLifecycleMetadata 构建元数据信息
private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType))) {
return this.emptyLifecycleMetadata;
}
// 存储@PostConstruct和@PreDestroy
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<>();
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
// 如果这个方法标注了@PostConstruct注解,添加到当前类init集合中
//setInitAnnotationType(PostConstruct.class);
if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {
LifecycleElement element = new LifecycleElement(method);
currInitMethods.add(element);
if (logger.isTraceEnabled()) {
logger.trace("Found init method on class [" + clazz.getName() + "]: " + method);
}
}
// 如果这个方法标注了@PreDestroy注解,添加到当前类destroy集合中
//setDestroyAnnotationType(PreDestroy.class);
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);
}
}
});
// 把当前类的@PostConstruct和@PreDestory添加到外部容器中,下面接下来继续找父类定义的信息注解信息
initMethods.addAll(0, currInitMethods);
destroyMethods.addAll(currDestroyMethods);
//获取父类
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
// 如果找到初始化方法或者销毁方法,那么会创建一个生命周期元数据的包装类,包装所有init方法和destroy方法
return (initMethods.isEmpty() && destroyMethods.isEmpty() ? this.emptyLifecycleMetadata :
new LifecycleMetadata(clazz, initMethods, destroyMethods));
}
metadata.checkConfigMembers(beanDefinition) 最终把合并后的放在成员中
// 如果beanDefinition中有配置,那么使用beanDefinition的,如果没有配置,使用注解配置的
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
Set<LifecycleElement> checkedInitMethods = new LinkedHashSet<>(this.initMethods.size());
for (LifecycleElement element : this.initMethods) {
//全限定类名+方法名
String methodIdentifier = element.getIdentifier();
//判断xml是否配置了init-method方法
if (!beanDefinition.isExternallyManagedInitMethod(methodIdentifier)) {
beanDefinition.registerExternallyManagedInitMethod(methodIdentifier);
//把检查后的方法添加到集合中
checkedInitMethods.add(element);
if (logger.isTraceEnabled()) {
logger.trace("Registered init method on class [" + this.targetClass.getName() + "]: " + element);
}
}
}
Set<LifecycleElement> checkedDestroyMethods = new LinkedHashSet<>(this.destroyMethods.size());
for (LifecycleElement element : this.destroyMethods) {
String methodIdentifier = element.getIdentifier();
if (!beanDefinition.isExternallyManagedDestroyMethod(methodIdentifier)) {
beanDefinition.registerExternallyManagedDestroyMethod(methodIdentifier);
checkedDestroyMethods.add(element);
if (logger.isTraceEnabled()) {
logger.trace("Registered destroy method on class [" + this.targetClass.getName() + "]: " + element);
}
}
}
// 最终把合并后的放在成员中
this.checkedInitMethods = checkedInitMethods;
this.checkedDestroyMethods = checkedDestroyMethods;
}
AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition 解析注解信息并添加到缓存
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
// 获取@Autowired和@Value注解的元数据
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
//合并处理bean定义信息属性
metadata.checkConfigMembers(beanDefinition);
}
findAutowiringMetadata 查找元数据信息
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
// 获取cache key
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);
// 这个检查方法比较有意思,上面咱们说ConcurrentHashMap的时候提了几个疑问,这里就用到了
// 判断的时候是根据==null || target != clazz 控制
// 说明存在并发修改,个人猜测会涉及到代理对象 *** 作
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
metadata = buildAutowiringMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
buildAutowiringMetadata 构建元数据信息
private InjectionMetadata buildAutowiringMetadata(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 -> {
// 找到@Autowired和@Value注解标注的属性
MergedAnnotation<?> ann = findAutowiredAnnotation(field);
if (ann != null) {
// 验证注解不能标注在静态方法上
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static fields: " + field);
}
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;
}
//从这里可以看出,autowired是可以添加到方法上的
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);
}
metadata.checkConfigMembers(beanDefinition) 合并定义信息,其实就是过滤
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
Set<InjectedElement> checkedElements = new LinkedHashSet<>(this.injectedElements.size());
for (InjectedElement element : this.injectedElements) {
Member member = element.getMember();
// 判断是否是别的地方(xml)属性是有配置,如果配置了,沿用(非注解配置)其他的,如果没有配置,沿用注解的
if (!beanDefinition.isExternallyManagedConfigMember(member)) {
beanDefinition.registerExternallyManagedConfigMember(member);
checkedElements.add(element);
}
}
this.checkedElements = checkedElements;
}
总结
applyMergedBeanDefinitionPostProcessors就是解析对应注解标注的属性和方法,解析完之后返回元数据信息,然后放到缓存中,下次使用的时候直接获取
如果xml中配置了,注解也标注了,那么默认会丢弃掉注解的配置,也就是xml配置优先级比较高
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)