Spring源码分析之Bean的创建过程详解 (4)

InitDestroyAnnotationBeanPostProcessor#postProcessMergedBeanDefinition

public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) { // 寻找PostConstruct @PreDestroy注解的方法 LifecycleMetadata metadata = findLifecycleMetadata(beanType); // 去重处理 metadata.checkConfigMembers(beanDefinition); }

所有的后置处理器的过程是相似的,这里取CommonAnnotationBeanPostProcessor进行分析

我们先来看看寻找元数据的过程

private InjectionMetadata findResourceMetadata(String beanName, final Class<?> clazz, @Nullable PropertyValues pvs) { String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName()); // 从缓存中获取 // 调用postProcessMergedBeanDefinition方法时将元数据解析放入缓存 // 调用postProcessProperties方法时将元数据取出 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); } // 创建元数据,寻找@Resouce标识的属性或方法 metadata = buildResourceMetadata(clazz); this.injectionMetadataCache.put(cacheKey, metadata); } } } return metadata; }

buildResourceMetadata

private InjectionMetadata buildResourceMetadata(final Class<?> clazz){ // 判断是否为候选的class,不是则返回默认的空元数据 // resourceAnnotationTypes为Annotation集合,里面包含了@Resource @EJB @WebServiceRef // 我们一般常用的只是@Resource if (!AnnotationUtils.isCandidateClass(clazz, resourceAnnotationTypes)) { return InjectionMetadata.EMPTY; } do { // 循环所有的属性,判断属性是否存在WebServiceRef、EJB、Resource注解,有则构建元数据 // doWithLocalFields中就是将targetClass的所有field取出进行循环 ReflectionUtils.doWithLocalFields(targetClass, field -> { if (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) { currElements.add(new WebServiceRefElement(field, field, null)); } else if (ejbClass != null && field.isAnnotationPresent(ejbClass)) { currElements.add(new EjbRefElement(field, field, null)); } // 是否存在@Resource注解 else if (field.isAnnotationPresent(Resource.class)) { if (!this.ignoredResourceTypes.contains(field.getType().getName())) { currElements.add(new ResourceElement(field, field, null)); } } }); // 与上一步相似,判断方法上是否存在这些注解 ReflectionUtils.doWithLocalMethods(targetClass, method -> { //......省略 }); // 获取父类 targetClass = targetClass.getSuperclass(); } // 父类不是Object则继续循环父类中的属性和方法 while (targetClass != null && targetClass != Object.class); // 将构建好的元数据封装到InjectionMetadata中返回 return InjectionMetadata.forElements(elements, clazz); }

现在我们再来看看去重处理的过程

public void checkConfigMembers(RootBeanDefinition beanDefinition) { Set<InjectedElement> checkedElements = new LinkedHashSet<>(this.injectedElements.size()); for (InjectedElement element : this.injectedElements) { Member member = element.getMember(); // 检查该beanDefinition的externallyManagedConfigMembers集合中是否已经包含该成员(属性或者方法) if (!beanDefinition.isExternallyManagedConfigMember(member)) { // 不包含则将该成员注册 beanDefinition.registerExternallyManagedConfigMember(member); // 加入到已检查的集合 checkedElements.add(element); } } this.checkedElements = checkedElements; }

由于第四次,用于获取早期对象时的处理的调用,在Spring的内置处理器中也没有相应的实现,跳过

这一步和第一步一样,在AOP时将会用到,我们放到下章分析

紧接着就是填充属性的步骤了

populateBean protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { // 在这里可进行中止填充属性操作,实现InstantiationAwareBeanPostProcessor接口 // 并postProcessAfterInstantiation返回false,则直接返回,不会再往下执行 // Spring内中的后置处理器皆返回的true if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { return; } } } } // 获得自动装配的类型,默认为0, // 这里只有xml配置,ImportBeanDefinitionRegistrar,BeanFactoryPostProcessor可进行改变 // Spring整合Mybatis中,将Mapper的自动装配类型改成了BY_TYPE, // 于是在Mapper得以在这里被填充SqlSessionTemplate,SqlSessionFactory属性 int resolvedAutowireMode = mbd.getResolvedAutowireMode(); if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); if (resolvedAutowireMode == AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) { // 获取到依赖的bean并放到newPvs中 autowireByType(beanName, mbd, bw, newPvs); } // 将新的属性列表赋给旧的引用 pvs = newPvs; } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpgxxy.html