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);
}
}
}
有三个后置处理器满足条件,按照调用先后顺序为:
-
CommonAnnotationBeanPostProcessor
-
AutowiredAnnotationBeanPostProcessor
-
ApplicationListenerDetector
CommonAnnotationBeanPostProcessor
-
扫描 @PostConstruct 和 @PreDestroy
-
扫描 @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
-
扫描@Autowired
-
扫描@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中。
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;
}
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接口的执行顺序,能够见名知意的接口不再解释。
-
第一组,invokeAwareMethods方法调用
- BeanNameAware
- BeanClassLoaderAware
- 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); } } }
-
第二组,applyBeanPostProcessorsBeforeInitialization方法调用
-
EnvironmentAware
-
EmbeddedValueResolverAware 这个知道的人可能不多,实现该接口能够获取Spring EL解析器,用户的自定义注解需要支持spel表达式的时候可以使用,非常方便。
-
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
Spring Bean生命周期
5个阶段
-
Bean定义加载完成 Definition
-
实例化 Instantiation
-
属性赋值 Populate
-
初始化 Initialization
-
销毁 Destruction
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有什么区别?