Springboot啟動過程中的這個BeanPostProcessor,你知道干什么的嗎
環(huán)境:Springboot2.3.12RELEASE
主要內(nèi)容:
MergedBeanDefinitionPostProcessor處理器的作用
MergedBeanDefinitionPostProcessor合并Bean定義處理器,該處理器有什么用處?通過源碼來查看具體的功能
這里從創(chuàng)建一個Bean實例開始說起。
1 環(huán)境準備
- @Component
- public class PersonDAOImpl implements PersonDAO {
- @Override
- public void save() {
- System.out.println("保存Person信息") ;
- }
- }
- @Service
- public class UsersService {
- @Autowired
- private PersonDAO personDAO ;
- public void saveUsers(Users users) {
- System.out.println("保存用戶信息") ;
- }
- }
2 創(chuàng)建實例
- public abstract class AbstractAutowireCapableBeanFactory {
- protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
- BeanWrapper instanceWrapper = null;
- if (instanceWrapper == null) {
- instanceWrapper = createBeanInstance(beanName, mbd, args);
- }
- // Allow post-processors to modify the merged bean definition.
- synchronized (mbd.postProcessingLock) {
- if (!mbd.postProcessed) {
- try {
- // 在創(chuàng)建實例后調(diào)用MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition方法
- applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
- } catch (Throwable ex) {
- }
- mbd.postProcessed = true;
- }
- }
- }
- }
3 執(zhí)行合并Bean定義方法
- public abstract class AbstractAutowireCapableBeanFactory {
- 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);
- }
- }
- }
- }
在這里符合要求的BeanPostProcessor對象有:
CommonAnnotationBeanPostProcessor和AutowiredAnnotationBeanPostProcessor(這里值列出重點的兩個)Common這個主要處理:@PostConstruct和@PreDestroy及@Resource等相關(guān)的注解;Autowired主要處理的是:@Autowired和@Value及@Inject注解
上面的準備的類中在UserService中通過@Autowired注入了PersonDAO對象,所以這里我們主要是看下
AutowiredAnnotationBeanPostProcessor處理器。
4 處理執(zhí)行
- public class AutowiredAnnotationBeanPostProcessor {
- private final Map<String, InjectionMetadata> injectionMetadataCache = new ConcurrentHashMap<>(256);
- private final Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<>(4);
- 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.
- }
- }
- 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.
- // 生成緩存使用的Key名稱,后續(xù)會通過該Key將對應(yīng)的信息緩存起來
- String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
- // 從當前的緩存中獲取是否存在
- InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
- // 該方法中會判斷緩存中是否存在,上面的metadata;以下通過雙重檢查
- if (InjectionMetadata.needsRefresh(metadata, clazz)) {
- synchronized (this.injectionMetadataCache) {
- metadata = this.injectionMetadataCache.get(cacheKey);
- if (InjectionMetadata.needsRefresh(metadata, clazz)) {
- if (metadata != null) {
- metadata.clear(pvs);
- }
- // 構(gòu)建自動裝配元信息;通過當前在這處理的class對象查找是否具有@Autowired注解信息(從字段和方法上查找)
- metadata = buildAutowiringMetadata(clazz);
- // 將查找到的InjectionMetadata緩存起來,在后續(xù)填充屬性的時候直接通過緩存獲取即可
- this.injectionMetadataCache.put(cacheKey, metadata);
- }
- }
- }
- return metadata;
- }
- 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<>();
- // 這里通過方法也能知道遍歷當前類中的所有字段,檢查是否有@Autowired注解
- ReflectionUtils.doWithLocalFields(targetClass, field -> {
- // 在字段上查找@Autowired注解信息
- MergedAnnotation<?> ann = findAutowiredAnnotation(field);
- if (ann != null) {
- // 判斷當前的字段是否通過static修飾了
- if (Modifier.isStatic(field.getModifiers())) {
- return;
- }
- // 判斷是否必須的字段(默認是true,要注入的Bean必須存在)
- boolean required = determineRequiredStatus(ann);
- // 將查找到的字段信息保存到AutowriedFieldElement中
- currElements.add(new AutowiredFieldElement(field, required));
- }
- });
- // 遍歷當前class中所有的方法,是否有@Autowired注解信息
- 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())) {
- return;
- }
- boolean required = determineRequiredStatus(ann);
- PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
- currElements.add(new AutowiredMethodElement(method, required, pd));
- }
- });
- elements.addAll(0, currElements);
- targetClass = targetClass.getSuperclass();
- // 遍歷當前的類及父類,一直找到父類為Object為止
- } while (targetClass != null && targetClass != Object.class);
- return InjectionMetadata.forElements(elements, clazz);
- }
- @Nullable
- private MergedAnnotation<?> findAutowiredAnnotation(AccessibleObject ao) {
- MergedAnnotations annotations = MergedAnnotations.from(ao);
- // 開始遍歷當前的字段(方法)上是否有autowiredAnnotationTypes集合中定義的注解(該集合在構(gòu)造該對象的時候就添加了)
- for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
- MergedAnnotation<?> annotation = annotations.get(type);
- if (annotation.isPresent()) {
- return annotation;
- }
- }
- return null;
- }
- }
- public abstract class ReflectionUtils {
- 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);
- }
- }
- }
- 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);
- }
- }
- }
- }
5 填充屬性
在這里的屬性填充會利用上面的緩存中之間取值進行屬性的注入
- public class AutowiredAnnotationBeanPostProcessor {
- public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
- // 這里會直接從緩存中(injectionMetadataCache)獲取
- InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
- // 屬性的填充注入
- metadata.inject(bean, beanName, pvs);
- return pvs;
- }
- 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;
- }
- }
以上就是
MergedBeanDefinitionPostProcessor處理器的作用了。