14.Spring扩展点总结

Spring扩展点总结

Spring扩展点

Spring生命周期相关的常用扩展点非常多,大家以后可能不是不知道,而是容易忘记,这里通过Spring的生命周期及源码的方式帮大家理解记忆。

bean定义Definition

在这个阶段包含了4个扩展点,他们的被调用顺序是

BeanDefinitionRegistryPostProcessor→ImpotSelector→ImportBeanDefinitionRegistrar→BeanFactoryPostProcessor

BeanDefinitionRegistryPostProcessor

BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口,所以不仅有自身的方法,还有BeanFactoryPostProcessor的方法,这个方法是在初始化bean工厂时调用的,这个时候还没有将所有bd注册进bean工厂,而它的工作也是对绝大部分bd的注册。

// 首先触发DefinitonRegistryPostProcessor,后面才是BeanFactoryPostProcessor
postProcessBeanDefinitionRegistry(BeanDefinitionRegistry):20,
MyBeanDefinitonRegistryPostProcessor (edu.dongnao.courseware.spring.ext)
// 真正执行的地方
invokeBeanDefinitionRegistryPostProcessors(Collection,
BeanDefinitionRegistry):280, PostProcessorRegistrationDelegate
(org.springframework.context.support)
invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory, List):126,
PostProcessorRegistrationDelegate (org.springframework.context.support)
// AbstractApplicationContext.refresh的invokeBeanFactoryPostProcessors方法
invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory):707,
AbstractApplicationContext (org.springframework.context.support)
// refresh
refresh():533, AbstractApplicationContext (org.springframework.context.support)
<init>(String[]):101, AnnotationConfigApplicationContext
(org.springframework.context.annotation)
main(String[]):13, AnnotationConfig (edu.dongnao.courseware.spring.runner)

调用处理顺序主要在下面的方法中进行

PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory, List)

BeanDefinitionRegistryPostProcessor接口有一个重要的实现类,也是spring内部的实现类,名字是ConfigurationClassPostProcessor,它在spring上下文对象的构造方法中就注册进了bean工厂,它的postProcessBeanDefinitionRegistry方法,也是BeanDefinitionRegistryPostProcessor特有的实现方法完成了对包的扫描并注册和对@Import注解的处理。

public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {

/**
	 * Derive further bean definitions from the configuration classes in the registry.
	 */
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
        int registryId = System.identityHashCode(registry);
        if (this.registriesPostProcessed.contains(registryId)) {
            throw new IllegalStateException(
                "postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
        }
        if (this.factoriesPostProcessed.contains(registryId)) {
            throw new IllegalStateException(
                "postProcessBeanFactory already called on this post-processor against " + registry);
        }
        this.registriesPostProcessed.add(registryId);

        processConfigBeanDefinitions(registry);
    }
}


/**
	 * Build and validate a configuration model based on the registry of
	 * {@link Configuration} classes.
	 */
	public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
		List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
		String[] candidateNames = registry.getBeanDefinitionNames();

		for (String beanName : candidateNames) {
			BeanDefinition beanDef = registry.getBeanDefinition(beanName);
			if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
				if (logger.isDebugEnabled()) {
					logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
				}
			}
			else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
				configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
			}
		}

		// Return immediately if no @Configuration classes were found
		if (configCandidates.isEmpty()) {
			return;
		}

		// Sort by previously determined @Order value, if applicable
		configCandidates.sort((bd1, bd2) -> {
			int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
			int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
			return Integer.compare(i1, i2);
		});

		// Detect any custom bean name generation strategy supplied through the enclosing application context
		SingletonBeanRegistry sbr = null;
		if (registry instanceof SingletonBeanRegistry) {
			sbr = (SingletonBeanRegistry) registry;
			if (!this.localBeanNameGeneratorSet) {
				BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
						AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
				if (generator != null) {
					this.componentScanBeanNameGenerator = generator;
					this.importBeanNameGenerator = generator;
				}
			}
		}

		if (this.environment == null) {
			this.environment = new StandardEnvironment();
		}

		// Parse each @Configuration class
		ConfigurationClassParser parser = new ConfigurationClassParser(
				this.metadataReaderFactory, this.problemReporter, this.environment,
				this.resourceLoader, this.componentScanBeanNameGenerator, registry);

		Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
		Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
		do {
			parser.parse(candidates);
			parser.validate();

			Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
			configClasses.removeAll(alreadyParsed);

			// Read the model and create bean definitions based on its content
			if (this.reader == null) {
				this.reader = new ConfigurationClassBeanDefinitionReader(
						registry, this.sourceExtractor, this.resourceLoader, this.environment,
						this.importBeanNameGenerator, parser.getImportRegistry());
			}
			this.reader.loadBeanDefinitions(configClasses);
			alreadyParsed.addAll(configClasses);

			candidates.clear();
			if (registry.getBeanDefinitionCount() > candidateNames.length) {
				String[] newCandidateNames = registry.getBeanDefinitionNames();
				Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
				Set<String> alreadyParsedClasses = new HashSet<>();
				for (ConfigurationClass configurationClass : alreadyParsed) {
					alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
				}
				for (String candidateName : newCandidateNames) {
					if (!oldCandidateNames.contains(candidateName)) {
						BeanDefinition bd = registry.getBeanDefinition(candidateName);
						if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
								!alreadyParsedClasses.contains(bd.getBeanClassName())) {
							candidates.add(new BeanDefinitionHolder(bd, candidateName));
						}
					}
				}
				candidateNames = newCandidateNames;
			}
		}
		while (!candidates.isEmpty());

		// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
		if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
			sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
		}

		if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
			// Clear cache in externally provided MetadataReaderFactory; this is a no-op
			// for a shared cache since it'll be cleared by the ApplicationContext.
			((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
		}
	}

ConfigurationClassParser的parse方法实现了ImpotSelector和ImportBeanDefinitionRegistrar的扩展调用,也决定了它们的执行顺序。

Mybatis中MapperScannerConfigurer实现了该接口,在只有接口没有实现类的情况下找到接口方法与sql之间的联系从而生成BeanDefinition并注册。

ImportSelector

这个接口的实现类因为是在@Import中注入的,所以自然这个类的回调方法也在BeanDefinitionRegistryPostProcessor的后调方法中执行的,它也是在初始化bean工厂时期调用的。这个实现类的回调方法比ImportBeanDefinitionRegistrar会稍微早一点,但是区别只是属于第一个判断而已,几乎同时期实现的。

注意这个时候扫描的类已经注册进了bean工厂。

ImportBeanDefinitionRegistrar

这个接口的实现类因为是在@Import中注入的,所以自然这个类的回调方法也在BeanDefinitionRegistryPostProcessor的后调方法中执行的,它也是在初始化bean工厂时期调用的。

注意这个时候扫描的类已经注册进了bean工厂。

当然还包含每天提到的@Configuration注解配置的bean也是在这个时候注册进bean工厂

BeanFactoryPostProcessor

在初始化完bean工厂的最后,这个时候绝大部分类已经注册进了bean工厂,包括扫描到的和@Import和@Import注入的类。

同时BeanDefinitionRegistryPostProcessor接口中实现的BeanFactoryPostProcessor的后调方法也会调用,不过会在BeanFactoryPostProcessor的实现类之前。

同样是ConfigurationClassPostProcessor实现的BeanFactoryPostProcessor的postProcessBeanFactory方法会对@Configuration类做cglib的动态代理。

PropertyPlaceholderConfigurer,在BeanDefinition生成后,可能某些参数是${key},这个实现类就是把前边这种参数转换成xxx.properties中key所对应的值。

实例化 Instantiation

已经实例化的bean时期调用的接口

InstantiationAwareBeanPostProcessor
实例化前

BeanPostProcessor子接口,用在实例化前后,属性填充。

实例化前引用AbstractAutowireCapableBeanFactory#createBean(String, RootBeanDefinition,Object[])方法。

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable
                            Object[] args) throws BeanCreationException {
    try {
        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
        // postProcessBeforeInstantiation方法调用点,这里就不跟进了,
        // 有兴趣的同学可以自己看下,就是for循环调用所有的InstantiationAwareBeanPostProcessor
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            return bean;
        }
    }
    try {
        // 上文提到的doCreateBean方法,可以看到
        // postProcessBeforeInstantiation方法在创建Bean之前调用
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);

        if (logger.isTraceEnabled()) {
            logger.trace("Finished creating instance of bean '" + beanName +
                         "'");
        }
        return beanInstance;
    }
}

resolveBeforeInstantiation

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
   Object bean = null;
   if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
      // Make sure bean class is actually resolved at this point.
      if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
         Class<?> targetType = determineTargetType(beanName, mbd);
         if (targetType != null) {
            bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
            if (bean != null) {
               bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
            }
         }
      }
      mbd.beforeInstantiationResolved = (bean != null);
   }
   return bean;
}

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
        if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
            if (result != null) {
                return result;
            }
        }
    }
    return null;
}

AbstractAutoProxyCreator#postProcessBeforeInstantiation方法

@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
   Object cacheKey = getCacheKey(beanClass, beanName);

   if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
      if (this.advisedBeans.containsKey(cacheKey)) {
         return null;
      }
      if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
         this.advisedBeans.put(cacheKey, Boolean.FALSE);
         return null;
      }
   }

   // Create proxy here if we have a custom TargetSource.
   // Suppresses unnecessary default instantiation of the target bean:
   // The TargetSource will handle target instances in a custom fashion.
   TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
   if (targetSource != null) {
      if (StringUtils.hasLength(beanName)) {
         this.targetSourcedBeans.add(beanName);
      }
      Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
      Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
      this.proxyTypes.put(cacheKey, proxy.getClass());
      return proxy;
   }

   return null;
}

可以看到,postProcessBeforeInstantiation在doCreateBean之前调用,也就是在bean实例化之前调用的,英文源码注释解释道该方法的返回值会替换原本的Bean作为代理,这是通过TargetSource实现Aop等功能实现的关键点。

实例化后

第一种:代理成功,就会执行实例化之后的applyBeanPostProcessorsAfterInitialization

第二种:在属性赋值阶段,poulate方法中调用。

MergedBeanDefinitionPostProcessor

BeanPostProcessor的子接口

public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {
}

创建完对象之后, 接下来, 就应该想办法对属性进行注入了, 其中就包括 @Autowired 注入,在注入之前需要对 @Autowired 进行扫描和解析,只是进行了扫描, 没有进行属性注入工作。

// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
    if (!mbd.postProcessed) {
        try {
            //调用属性合并后置处理器, 进行属性合并
            //这里会进行 一些注解 的扫描
            //CommonAnnotationBeanPostProcessor -> @PostConstruct @PreDestroy @Resource
            //AutowiredAnnotationBeanPostProcessor -> @Autowired @Value
            applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(mbd.getResourceDescription(),
                                            beanName,
                                            "Post-processing of merged bean definition failed", ex);
        }
        mbd.postProcessed = true;
    }
}

applyMergedBeanDefinitionPostProcessors方法实现

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);
      }
   }
}

有三个后置处理器满足条件,按照调用先后顺序为:

  1. CommonAnnotationBeanPostProcessor

  2. AutowiredAnnotationBeanPostProcessor

  3. ApplicationListenerDetector

CommonAnnotationBeanPostProcessor
  1. 扫描 @PostConstruct 和 @PreDestroy

  2. 扫描 @Resource , 这个需要到 findResourceMetadata 中, 才能看到

    static {
       webServiceRefClass = loadAnnotationType("javax.xml.ws.WebServiceRef");
       ejbClass = loadAnnotationType("javax.ejb.EJB");
    
       resourceAnnotationTypes.add(Resource.class);
       if (webServiceRefClass != null) {
          resourceAnnotationTypes.add(webServiceRefClass);
       }
       if (ejbClass != null) {
          resourceAnnotationTypes.add(ejbClass);
       }
    }
    //......
    
    public CommonAnnotationBeanPostProcessor() {
        setOrder(Ordered.LOWEST_PRECEDENCE - 3);
        setInitAnnotationType(PostConstruct.class);
        setDestroyAnnotationType(PreDestroy.class);
        ignoreResourceType("javax.xml.ws.WebServiceContext");
    }
    
AutowiredAnnotationBeanPostProcessor
  1. 扫描@Autowired

  2. 扫描@Value

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.
   }
}

AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata

@Override
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.
    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;
}

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<>();
		// 通过反射获取该类所有的字段,并遍历每一个字段,通过方法findAutowiredAnnotation 遍历每一个字段的所用注解,
		// 如果用autowired修饰了,则返回 auotowired 相关属性
        ReflectionUtils.doWithLocalFields(targetClass, field -> {
            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));
            }
        });

        // 通过反射处理类的method
        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));
            }
        });

        // 用@Autowired修饰的注解可能不止一个,因此都加在 elements 这个容器里面,一起处理
        elements.addAll(0, currElements);
        targetClass = targetClass.getSuperclass();
    }
    while (targetClass != null && targetClass != Object.class);

    return InjectionMetadata.forElements(elements, clazz);
}
ApplicationListenerDetector

记录了容器中的 bean 是否是单例模式,这个标志, 是为了后面用的,对监听器进行过滤用的

@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
   if (ApplicationListener.class.isAssignableFrom(beanType)) {
      this.singletonNames.put(beanName, beanDefinition.isSingleton());
   }
}
SmartInstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor的子接口,用在单例bean循环引用场景,AOP代理提前暴露bean引用。

SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference方法的实现在AbstractAutoProxyCreator#getEarlyBeanReference中。

image-20241226120031432

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
   Object exposedObject = bean;
   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
            SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
            exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
         }
      }
   }
   return exposedObject;
}

image-20241226120246125

Aware接口

属性赋值Populate

InstantiationAwareBeanPostProcessor
实例化后

先进行postProcessAfterInstantiation方法的调用

该方法在属性赋值方法内,但是在真正执行赋值操作之前。其返回值为boolean,返回false时可以阻断属性赋值阶段。

再进行postProcessProperties方法调用

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
   if (bw == null) {
      if (mbd.hasPropertyValues()) {
         throw new BeanCreationException(
               mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
      }
      else {
         // Skip property population phase for null instance.
         return;
      }
   }

   // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
   // state of the bean before properties are set. This can be used, for example,
   // to support styles of field injection.
   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
               return;
            }
         }
      }
   }

   PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

   int resolvedAutowireMode = mbd.getResolvedAutowireMode();
   if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
      MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
      // Add property values based on autowire by name if applicable.
      if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
         autowireByName(beanName, mbd, bw, newPvs);
      }
      // Add property values based on autowire by type if applicable.
      if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
         autowireByType(beanName, mbd, bw, newPvs);
      }
      pvs = newPvs;
   }

   boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
   boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

   PropertyDescriptor[] filteredPds = null;
   if (hasInstAwareBpps) {
      if (pvs == null) {
         pvs = mbd.getPropertyValues();
      }
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
            if (pvsToUse == null) {
               if (filteredPds == null) {
                  filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
               }
               pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
               if (pvsToUse == null) {
                  return;
               }
            }
            pvs = pvsToUse;
         }
      }
   }
   if (needsDepCheck) {
      if (filteredPds == null) {
         filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
      }
      checkDependencies(beanName, mbd, filteredPds, pvs);
   }

   if (pvs != null) {
      applyPropertyValues(beanName, mbd, bw, pvs);
   }
}

初始化 Initializtion

AbstractAutowireCapableBeanFactory#initializeBean(Object, RootBeanDefinition)

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    // Aware接口扩展
   if (System.getSecurityManager() != null) {
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
         invokeAwareMethods(beanName, bean);
         return null;
      }, getAccessControlContext());
   }
   else {
      invokeAwareMethods(beanName, bean);
   }

   Object wrappedBean = bean;
   if (mbd == null || !mbd.isSynthetic()) {
       // 初始化前,BeanPostProcessor.postProcessBeforeInitialization
		// 调用剩下的Aware接口
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }

   try {
       // 初始化处理
        // 1. 处理InitializingBean.afterPropertiesSet
        // 2. 调用bean定义initMethod
      invokeInitMethods(beanName, wrappedBean, mbd);
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            (mbd != null ? mbd.getResourceDescription() : null),
            beanName, "Invocation of init method failed", ex);
   }
   if (mbd == null || !mbd.isSynthetic()) {
       // 初始化后,BeanPostProcessor.postProcessAfterInitialization
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }

   return wrappedBean;
}
Aware接口

​ Aware类型的接口的作用就是让我们能够拿到Spring容器中的一些资源。基本都能够见名知意,Aware之前的名字就是可以拿到什么资源,例如 BeanNameAware 可以拿到BeanName,以此类推。调用时机需要注意:所有的Aware方法都是在初始化阶段之前调用的!

​ Aware接口众多,这里同样通过分类的方式帮助大家记忆。 Aware接口具体可以分为两组,至于为什么这么分,详见下面的源码分析。如下排列顺序同样也是Aware接口的执行顺序,能够见名知意的接口不再解释。

  1. 第一组,invokeAwareMethods方法调用

    1. BeanNameAware
    2. BeanClassLoaderAware
    3. BeanFactoryAware
    private void invokeAwareMethods(String beanName, Object bean) {
       if (bean instanceof Aware) {
          if (bean instanceof BeanNameAware) {
             ((BeanNameAware) bean).setBeanName(beanName);
          }
          if (bean instanceof BeanClassLoaderAware) {
             ClassLoader bcl = getBeanClassLoader();
             if (bcl != null) {
                ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
             }
          }
          if (bean instanceof BeanFactoryAware) {
             ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
          }
       }
    }
    
  2. 第二组,applyBeanPostProcessorsBeforeInitialization方法调用

    1. EnvironmentAware

    2. EmbeddedValueResolverAware 这个知道的人可能不多,实现该接口能够获取Spring EL解析器,用户的自定义注解需要支持spel表达式的时候可以使用,非常方便。

    3. ApplicationContextAware(ResourceLoaderAware\ApplicationEventPublisherAware\MessageSourceAware) 这几个接口可能让人有点懵,实际上这几个接口可以一起记,其返回值实质上都是当前的ApplicationContext对象,因为ApplicationContext是一个复合接口ApplicationContextAwareProcessor#postProcessBeforeInitialization

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
       if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
             bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
             bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
          return bean;
       }
    
       AccessControlContext acc = null;
    
       if (System.getSecurityManager() != null) {
          acc = this.applicationContext.getBeanFactory().getAccessControlContext();
       }
    
       if (acc != null) {
          AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
             invokeAwareInterfaces(bean);
             return null;
          }, acc);
       }
       else {
          invokeAwareInterfaces(bean);
       }
    
       return bean;
    }
    

ApplicationContext和BeanFactory的区别,可以从ApplicationContext继承的这几个接口入手,除去BeanFactory相关的两个接口就是ApplicationContext独有的功能,这里不详细说明。

BeanPostProcessor

在refresh方法中的registerBeanPostProcessors,BeanPostProcessor也会注册为Bean。

初始化前

BeanPostProcessor#postProcessBeforeInitialization

AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization

对应的实现类

AbstractAdvisingBeanPostProcessor
AbstractAutoProxyCreator
AdvisorAdapterRegistrationManager
ApplicationContextAwareProcessor
ApplicationListenerDetector
BeanPostProcessorChecker in PostProcessorRegistrationDelegate
BeanValidationPostProcessor
BootstrapContextAwareProcessor
ImportAwareBeanPostProcessor in ConfigurationClassPostProcessor
InitDestroyAnnotationBeanPostProcessor
InstantiationAwareBeanPostProcessorAdapter
LoadTimeWeaverAwareProcessor
ScheduledAnnotationBeanPostProcessor

BeanPostProcessor有很多个,而且每个BeanPostProcessor都影响多个Bean,其执行顺序至关重要,必须能够控制其执行顺序才行。关于执行顺序这里需要引入两个排序相关的接口:PriorityOrdered、Ordered。

  • PriorityOrdered是一等公民,首先被执行,PriorityOrdered公民之间通过接口返回值排序
  • Ordered是二等公民,然后执行,Ordered公民之间通过接口返回值排序
  • 都没有实现是三等公民,最后执行

registerBeanPostProcessors方法的代理实现中进行了相关排序的计算处理。

其中AbstractAutoProxyCreator是非常重要的AOP实现,只不过在初始化之前,AOP中的没有做任何实现。

初始化后

BeanPostProcessor#postProcessAfterInitialization

AbstractAdvisingBeanPostProcessor
AbstractAutoProxyCreator
AdvisorAdapterRegistrationManager
ApplicationListenerDetector
BeanPostProcessorChecker in PostProcessorRegistrationDelegate
BeanValidationPostProcessor
BootstrapContextAwareProcessor
InitDestroyAnnotationBeanPostProcessor
InstantiationAwareBeanPostProcessorAdapter
LoadTimeWeaverAwareProcessor
ScheduledAnnotationBeanPostProcessor

AbstractAutoProxyCreator的postProcessAfterInitialization实现了对bean进行了AOP代理。

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
   if (bean != null) {
      Object cacheKey = getCacheKey(bean.getClass(), beanName);
      if (this.earlyProxyReferences.remove(cacheKey) != bean) {
         return wrapIfNecessary(bean, beanName, cacheKey);
      }
   }
   return bean;
}
InitializingBean

AbstractAutowireCapableBeanFactory#invokeInitMethods

protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
      throws Throwable {

   boolean isInitializingBean = (bean instanceof InitializingBean);
   if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
      if (logger.isTraceEnabled()) {
         logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
      }
      if (System.getSecurityManager() != null) {
         try {
            AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
               ((InitializingBean) bean).afterPropertiesSet();
               return null;
            }, getAccessControlContext());
         }
         catch (PrivilegedActionException pae) {
            throw pae.getException();
         }
      }
      else {
         ((InitializingBean) bean).afterPropertiesSet();
      }
   }

   if (mbd != null && bean.getClass() != NullBean.class) {
      String initMethodName = mbd.getInitMethodName();
      if (StringUtils.hasLength(initMethodName) &&
            !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
            !mbd.isExternallyManagedInitMethod(initMethodName)) {
         invokeCustomInitMethod(beanName, bean, mbd);
      }
   }
}

此时,Bean初始化完成,业务中可以正常调用该bean了。

销毁Destruction

当容器关闭的时候,会触发销毁方法调用

注册销毁回调

AbstractBeanFactory#registerDisposableBeanIfNecessary

DisposableBean
public interface DisposableBean {

   /**
    * Invoked by the containing {@code BeanFactory} on destruction of a bean.
    * @throws Exception in case of shutdown errors. Exceptions will get logged
    * but not rethrown to allow other beans to release their resources as well.
    */
   void destroy() throws Exception;

}
DestructionAwareBeanPostProcessor

BeanPostProcessor的子接口

触发销毁

AbstractApplicationContext#close

总结

粗略扩展点
  • 定义加载完成

    BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor

    ImportSelector、ImportBeanDefinitionRegistrar

  • 实例化

    InstantiationAwareBeanPostProcessor

  • 初始化

    BeanPostProcessor、InitializingBean

  • 销毁

    ​ DisposableBean

image-20241226122206702

Spring Bean生命周期

5个阶段

  1. Bean定义加载完成 Definition

  2. 实例化 Instantiation

  3. 属性赋值 Populate

  4. 初始化 Initialization

  5. 销毁 Destruction

image-20241226122305980

BeanFacoty与ApplicationContext有什么区别?

{@code BeanFactory} on destruction of a bean.
* @throws Exception in case of shutdown errors. Exceptions will get logged
* but not rethrown to allow other beans to release their resources as well.
*/
void destroy() throws Exception;

}


##### DestructionAwareBeanPostProcessor

BeanPostProcessor的子接口

#### 触发销毁

AbstractApplicationContext#close

### 总结

#### 粗略扩展点

- 定义加载完成

  BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor

  ImportSelector、ImportBeanDefinitionRegistrar

- 实例化

  InstantiationAwareBeanPostProcessor

- 初始化

  BeanPostProcessor、InitializingBean

- 销毁

  ​     DisposableBean

[外链图片转存中...(img-KGrDJP9P-1748071686942)]

#### Spring Bean生命周期

5个阶段

1. Bean定义加载完成 Definition

2. 实例化 Instantiation

3. 属性赋值 Populate

4. 初始化 Initialization

5. 销毁 Destruction

[外链图片转存中...(img-cdAiXiay-1748071686942)]

#### BeanFacoty与ApplicationContext有什么区别?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值