Spring bean生命周期详解

2023-11-04

Spring Bean的完整生命周期从创建Spring容器开始,直到最终Spring容器销毁Bean,这其中包含了一系列关键点。
在这里插入图片描述
在这里插入图片描述

Spring bean生命周期 四个阶段

Bean的实例化阶段
Bean的设置属性阶段
Bean的 初始化阶段
Bean的销毁阶段

Spring bean生命周期13个环节

阶段1:Bean元信息配置阶段
阶段2:Bean元信息解析阶段
阶段3:将Bean注册到容器中
阶段4:BeanDefinition合并阶段
阶段5:Bean Class加载阶段
阶段6:Bean实例化阶段(2个小阶段)
1.Bean实例化前阶段
2.Bean实例化阶段
阶段7:合并后的BeanDefinition处理
阶段8:属性赋值阶段(3个小阶段)
1.Bean实例化后阶段
2.Bean属性赋值前阶段
3.Bean属性赋值阶段
阶段9:Bean初始化阶段(5个小阶段)
1.Bean Aware接口回调阶段
2.Bean初始化前阶段
3.Bean初始化阶段
4.Bean初始化后阶段
5.Bean初始化完成
阶段10:所有单例bean初始化完成后阶段
阶段11:Bean的使用阶段
阶段12:Bean销毁前阶段
阶段13:Bean销毁阶段

阶段1:Bean元信息配置阶段

这个阶段主要是bean信息的定义阶段
Bean信息定义4种方式

  1. API的方式
  2. Xml文件方式
  3. 注解的方式
    类上标注@Compontent注解来定义一个bean
    配置类中使用@Bean注解来定义bean
  4. properties文件的方式
    Spring容器启动的过程中,会将Bean解析成Spring内部的BeanDefinition结构。

不管是是通过xml配置文件的标签,还是通过注解配置的@Bean,还是@Compontent标注的类,还是扫描得到的类,它最终都会被解析成一个BeanDefinition对象,最后我们的Bean工厂就会根据这份Bean的定义信息,对bean进行实例化、初始化等等操作。

你可以把BeanDefinition丢给Bean工厂或者其子类,然后Bean工厂就会根据这个信息帮你生产一个Bean实例
一般用的是beanFactory的子类applicationcontext, applicationcontext比一般的beanFactory要多很多功能,比如aop、事件等。
通过t加载配置文件,或者利用注解的方式扫描将bean的配置信息加载到spring容器里面。

在这里插入图片描述

BeanDefinition接口:bean定义信息接口
AttributeAccessor接口:属性访问接口
BeanMetadataElement接口:返回BeanDefinition定义的来源
RootBeanDefinition类:表示根bean定义信息
ChildBeanDefinition类:表示子bean定义信息
GenericBeanDefinition类:通用的bean定义信息
ConfigurationClassBeanDefinition类:表示通过配置类中@Bean方法定义bean信息
AnnotatedBeanDefinition接口:表示通过注解的方式定义的bean信息
BeanDefinitionBuilder:构建BeanDefinition的工具类,可以非常方便的组装BeanDefinition对象

@Component 和 @Bean 的区别

Spring帮助我们管理Bean分为两个部分,一个是注册Bean,一个装配Bean。
完成这两个动作有三种方式,一种是使用自动配置的方式、一种是使用JavaConfig的方式,一种就是使用XML配置的方式。

@Compent 作用就相当于 XML配置

@Component
public class Student {

    private String name = "lkm";

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

@Bean 需要在配置类中使用,即类上需要加上@Configuration注解

@Configuration
public class WebSocketConfig {
    @Bean
    public Student student(){
        return new Student();
    }

}

两者都可以通过@Autowired装配

@Autowired Student student;

那为什么有了@Compent,还需要@Bean呢?
如果你想要将第三方库中的组件装配到你的应用中,在这种情况下,是没有办法在它的类上添加@Component注解的,因此就不能使用自动化装配的方案了,但是我们可以使用@Bean,当然也可以使用XML配置。

阶段2:Bean元信息解析阶段

Bean元信息的解析主要有3种方式

  1. xml文件定义bean的解析
    XML方式解析:XmlBeanDefinitionReader
  2. properties文件定义bean的解析
    properties文件定义bean的解析:PropertiesBeanDefinitionReader
  3. 注解方式定义bean的解析
    AnnotatedBeanDefinitionReader
    BeanDefinationReader的作用就是加载配置元信息,并将其转化为内存形式的BeanDefination

阶段3:Spring Bean注册阶段

bean注册阶段需要用到一个非常重要的接口:BeanDefinitionRegistry

别名注册接口:AliasRegistry
BeanDefinitionRegistry接口继承了AliasRegistry接口,这个接口中定义了操作bean别名的一些方法。

BeanDefinitionRegistry唯一实现:DefaultListableBeanFactory
org.springframework.beans.factory.support.DefaultListableBeanFactory
例如 AnnotationConfigApplicationContext 类就实现了 BeanDefinitionRegistry接口

Spring通过BeanDefinationReader将配置元信息加载到内存生成相应的BeanDefination之后,就将其注册到BeanDefinationRegistry中,BeanDefinationRegistry就是一个存放BeanDefination的大篮子,它也是一种键值对的形式,通过特定的Bean定义的id,映射到相应的BeanDefination。

getBean这个方法的源码
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean

阶段4:BeanDefinition合并阶段

org.springframework.beans.factory.support.AbstractBeanFactory#getMergedBeanDefinition
bean定义可能存在多级父子关系,合并的时候进进行递归合并,最终得到一个包含完整信息的RootBeanDefinition.

合并之前是GenericBeanDefinition类型的,合并之后得到的是RootBeanDefinition类型的。

后面的阶段将使用合并产生的RootBeanDefinition

阶段5:Bean Class加载阶段

这个阶段就是将bean的class名称转换为Class类型的对象。

此时会对阶段4中合并产生的RootBeanDefinition中的beanClass进行解析,将bean的类名转换为Class对象,然后赋值给RootBeanDefinition#setBeanClassName字段

上面得到了Bean Class对象以及合并之后的BeanDefinition,下面就开始进入实例化这个对象的阶段了。
Bean实例化分为3个阶段:前阶段、实例化阶段、后阶段;

阶段6:Bean实例化阶段

Bean实例化前操作

看一下 DefaultListableBeanFactory

在 父类 AbstractBeanFactory 中
private final List beanPostProcessors = new CopyOnWriteArrayList<>();
是一个BeanPostProcessor类型的集合

spring在bean生命周期的不同阶段,会调用上面这个列表中的BeanPostProcessor中的一些方法,来对生命周期进行扩展,bean生命周期中的所有扩展点都是依靠这个集合中的BeanPostProcessor来实现的

Bean实例化之前会调用一段代码:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation

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

上面代码中轮询beanPostProcessors列表,如果类型是InstantiationAwareBeanPostProcessor, 尝试调用InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation获取bean的实例对象,如果能够获取到,那么将返回值作为当前bean的实例,那么spring自带的实例化bean的过程就被跳过了.

这个地方给开发者提供了一个扩展点,允许开发者在这个方法中直接返回bean的一个实例

Bean实例化操作
这个过程可以干什么?

这个过程会通过反射来调用bean的构造器来创建bean的实例。
org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors
这个方法会返回候选的构造器列表,也可以返回空.

protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(Class<?> beanClass, String beanName)
			throws BeansException {

		if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
					Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
					if (ctors != null) {
						return ctors;
					}
				}
			}
		}
		return null;
	}

具体需要使用哪个构造器,spring为开发者提供了一个接口,允许开发者自己来判断用哪个构造器。
重要的实现类 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
可以将@Autowired标注的方法作为候选构造器返回
到目前为止bean实例化阶段结束了

阶段7:合并后的BeanDefinition处理

这块的源码如下
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#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);
		}
	}
}

会调用MergedBeanDefinitionPostProcessor接口的postProcessMergedBeanDefinition方法

第一个参数为beanDefinition,表示合并之后的RootBeanDefinition,我们可以在这个方法内部对合并之后的BeanDefinition进行再次处理

实现类
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
在 postProcessMergedBeanDefinition 方法中对 @Autowired、@Value 标注的方法、字段进行缓存

org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
在 postProcessMergedBeanDefinition 方法中对 @Resource 标注的字段、@Resource 标注的方法、 @PostConstruct 标注的字段、 @PreDestroy标注的方法进行缓存

阶段8:Bean属性设置阶段

(1)调用 InstantiationAwareBeanPostProcessor 处理器的 postProcessAfterInstantiation 方法,判断控制程序是否继续进行属性填充

(2)根据注入类型(byType/byName),提取依赖的,统一存入 PropertyValues 中

(3)判断是否需要进行 BeanPostProcessor 和 依赖检查:

如果有后置处理器,将会应用 InstantiationAwareBeanPostProcessor 处理器的postProcessProperties 方法,对属性获取完毕填充前,对属性进行再次处理。 使用 checkDependencies方法来进行依赖检查
(4)将所有解析到的 PropertyValues 中的属性填充至 BeanWrapper 中

实例化后阶段
会调用InstantiationAwareBeanPostProcessor接口的postProcessAfterInstantiation这个方法,调用逻辑如下:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
		throws BeansException {

	Object result = existingBean;
	for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
		result = beanProcessor.postProcessAfterInitialization(result, beanName);
		if (result == null) {
			return result;
		}
	}
	return result;
}

postProcessAfterInstantiation方法返回false的时候,后续的Bean属性赋值前处理、Bean属性赋值都会被跳过

Bean属性赋值前阶段
这个阶段会调用InstantiationAwareBeanPostProcessor接口的postProcessPropertyValues方法,调用逻辑
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean

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

如果InstantiationAwareBeanPostProcessor中的postProcessPropertyValues返回空的时候,表示这个bean不需要设置属性,直接返回了,直接进入下一个阶段
PropertyValues 保存了bean实例对象中所有属性值的设置,所以我们可以在postProcessPropertyValues 这个方法中对PropertyValues值进行修改。

这个方法有2个比较重要的实现类

AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues在这个方法中对@Autowired、@Value标注的字段、方法注入值。
CommonAnnotationBeanPostProcessor#postProcessPropertyValues在这个方法中对@Resource标注的字段和方法注入值。
Bean属性赋值阶段
这个过程比较简单了,循环处理PropertyValues中的属性值信息,通过反射调用set方法将属性的值设置到bean实例中。

PropertyValues中的值是通过bean xml中property元素配置的,或者调用MutablePropertyValues中add方法设置的值。

阶段9:Bean初始化阶段

这个阶段分为5个小的阶段

Bean Aware接口回调
Bean初始化前操作
Bean初始化操作
Bean初始化后操作
Bean初始化完成操作
Bean Aware接口回调

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods

private void invokeAwareMethods(final String beanName, final Object bean) {
		if (bean instanceof Aware) {
			if (bean instanceof BeanNameAware) {
				((BeanNameAware) bean).setBeanName(beanName);
			}
			if (bean instanceof BeanClassLoaderAware) {
				((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
			}
			if (bean instanceof BeanFactoryAware) {
				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
			}
		}
	}

如果我们的bean实例实现了上面的接口,会按照下面的顺序依次进行调用,

BeanNameAware:将bean的名称注入进去
BeanClassLoaderAware:将BeanClassLoader注入进去
BeanFactoryAware:将BeanFactory注入进去

Bean初始化前操作
这个阶段的源码
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization

@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
		throws BeansException {

	Object result = existingBean;
	for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
		result = beanProcessor.postProcessBeforeInitialization(result, beanName);
		if (result == null) {
			return result;
		}
	}
	return result;
}

会调用BeanPostProcessor的postProcessBeforeInitialization方法,若返回null,当前方法将结束。

通常称postProcessBeforeInitialization这个方法为:bean初始化前操作。

这个接口有2个实现类,比较重要:
org.springframework.context.support.ApplicationContextAwareProcessor
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor

ApplicationContextAwareProcessor注入6个Aware接口对象
如果bean实现了下面的接口,在ApplicationContextAwareProcessor#postProcessBeforeInitialization中会依次调用下面接口中的方法,将Aware前缀对应的对象注入到bean实例中。
EnvironmentAware:注入Environment对象 EmbeddedValueResolverAware:注入EmbeddedValueResolver对象 ResourceLoaderAware:注入ResourceLoader对象 ApplicationEventPublisherAware:注入ApplicationEventPublisher对象 MessageSourceAware:注入MessageSource对象 ApplicationContextAware:注入ApplicationContext对象

CommonAnnotationBeanPostProcessor调用@PostConstruct标注的方法
CommonAnnotationBeanPostProcessor#postProcessBeforeInitialization中会调用bean中所有标注@PostConstruct注解的方法

ReflectionUtils.doWithLocalMethods(targetClass, new ReflectionUtils.MethodCallback() {
	@Override
	public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
		if (initAnnotationType != null) {
			if (method.getAnnotation(initAnnotationType) != null) {
				LifecycleElement element = new LifecycleElement(method);
				currInitMethods.add(element);
				if (debug) {
					logger.debug("Found init method on class [" + clazz.getName() + "]: " + method);
				}
			}
		}
		if (destroyAnnotationType != null) {
			if (method.getAnnotation(destroyAnnotationType) != null) {
				currDestroyMethods.add(new LifecycleElement(method));
				if (debug) {
					logger.debug("Found destroy method on class [" + clazz.getName() + "]: " + method);
				}
			}
		}
	}
})

调用@PostConstruct标注的方法

Bean初始化阶段
2个步骤
调用InitializingBean接口的afterPropertiesSet方法
调用定义bean的时候指定的初始化方法。
见:com.dn.spring.beandefinition.BeanDefinition5Test#test7

Bean初始化后阶段
这块的源码:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {

	Object result = existingBean;
	for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
		result = beanProcessor.postProcessAfterInitialization(result, beanName);
		if (result == null) {
			return result;
		}
	}
	return result;
}

调用BeanPostProcessor接口的postProcessAfterInitialization方法,返回null的时候,会中断上面的操作。
通常称 postProcessAfterInitialization 这个方法为:bean初始化后置操作。

阶段10:所有单例bean初始化完成后阶段

所有单例bean实例化完成之后,spring会回调下面这个接口:

public interface SmartInitializingSingleton {
    void afterSingletonsInstantiated();
}

调用逻辑在下面这个方法中
//确保所有非lazy的单例都被实例化,同时考虑到FactoryBeans。 //如果需要,通常在工厂设置结束时调用。 org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons

这个方法内部会先触发所有非延迟加载的单例bean初始化,然后从容器中找到类型是SmartInitializingSingleton的bean,调用他们的afterSingletonsInstantiated方法。

阶段11:Bean使用阶段

调用getBean方法得到了bean之后

阶段12:Bean销毁阶段

触发bean销毁的几种方式

调用org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#destroyBean
调用org.springframework.beans.factory.config.ConfigurableBeanFactory#destroySingletons
调用ApplicationContext中的close方法
Bean销毁阶段会依次执行

轮询beanPostProcessors列表,如果是DestructionAwareBeanPostProcessor这种类型的,会调用其内部的postProcessBeforeDestruction方法
如果bean实现了org.springframework.beans.factory.DisposableBean接口,会调用这个接口中的destroy方法
调用bean自定义的销毁方法
DestructionAwareBeanPostProcessor接口

public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {

    /**
     * bean销毁前调用的方法
     */
    void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;

    /**
     * 用来判断bean是否需要触发postProcessBeforeDestruction方法
     */
    default boolean requiresDestruction(Object bean) {
        return true;
    }
}

总结:

BeanDefination(bean定义配置-解析-注册):

配置元信息(bean定义配置)-BeanDefinationReader(解析)-BeanDefinationRegistry(注册);
配置元信息(bean定义配置):API的方式,Xml文件方式,注解的方式,properties文件
BeanDefinationRegistry:;键值对方式,通过特定的Bean定义的id,映射到相应的BeanDefination

Bean实例化阶段:Bean实例化分为3个阶段:前阶段(容器启动,Bean Class加载BeanDefination)、实例化阶段、后阶段;

BeanFactoryPostProcessor:是容器启动阶段Spring提供的一个扩展点,主要对注册的BeanDefination进行一定程度上的修改与替换。
例如类名、scope、属性、构造函数参数列表、依赖的bean、是否是单例类、是否是懒加载等,
容器的启动阶段的最终产物就是注册到BeanDefinationRegistry中的一个个BeanDefination了,这就是Spring为Bean实例化所做的预热的工作。

spring bean实例化之后,就开始注入属性,
首先注入自定义的属性,比如标注@autowrite的这些属性,
再调用各种Aware接口扩展方法,注入属性(spring特有的属性),
比如BeanNameAware.setBeanName,设置Bean的ID或者Name;

在这里插入图片描述

a.实例化Bean
容器通过获取BeanDefinition对象中的信息进行实例化。并且这一步仅仅是简单的实例化,并未进行依赖注入。

对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBean进行实例化。
对于ApplicationContext容器,当容器启动结束后,便实例化所有的bean。

实例化对象被包装在BeanWrapper对象中(可以认为是Bean的原生态),BeanWrapper提供了设置对象属性的接口,避免了使用反射机制设置属性。

这里提到了4个组件:BeanFacotry\ApplicationContext\BeanDefinition\BeanWrapper

b.设置对象属性(依赖注入)
实例化后的对象被封装在BeanWrapper对象中,并且此时对象仍然是一个原生的状态,并没有进行依赖注入。
紧接着,Spring根据BeanDefinition中的信息进行依赖注入。
并且通过BeanWrapper提供的设置属性的接口完成依赖注入。

c.注入Aware接口(给bean增加某种能力,申明是某种特殊的bean)
Aware接口用于增强Bean能力容器需检测该对象是否实现了xxxAware接口,并将相关的xxxAware实例注入给bean。
常见的Aware接口有:BeanNameAware\BeanFactoryAware\ApplicationContextAware至此,一个对象已经被正确构造。

d.1.BeanPostProcessor(自定义处理,满足用户需求)
经过上述几个步骤后,bean对象已经被正确构造,但如果你想要对象被使用前再进行一些自定义的处理,就可以通过BeanPostProcessor接口实现。 该接口提供了两个函数:

postProcessBeforeInitialzation( Object bean, String beanName )
当前正在初始化的bean对象会被传递进来,我们就可以对这个bean作任何处理。 这个函数会先于InitialzationBean执行,因此称为前置处理。所有Aware接口的注入就是在这一步完成的。

postProcessAfterInitialzation( Object bean, String beanName )
当前正在初始化的bean对象会被传递进来,我们就可以对这个bean作任何处理。 这个函数会在InitialzationBean完成后执行,因此称为后置处理。
组件:BeanPostProcessor

d.2.InitializingBean与init-method
当BeanPostProcessor的前置处理完成后就会进入本阶段。 InitializingBean接口只有一个函数:afterPropertiesSet()这一阶段也可以在bean正式构造完成前增加我们自定义的逻辑,但它与前置处理不同,由于该函数并不会把当前bean对象传进来,因此在这一步没办法处理对象本身,只能增加一些额外的逻辑。
若要使用它,我们需要让bean实现该接口,并把要增加的逻辑写在该函数中。然后Spring会在前置处理完成后检测当前bean是否实现了该接口,并执行afterPropertiesSet函数。
当然,Spring为了降低对客户代码的侵入性,给bean的配置提供了init-method属性,该属性指定了在这一阶段需要执行的函数名。Spring便会在初始化阶段执行我们设置的函数。init-method本质上仍然使用了InitializingBean接口。

e.DisposableBean和destroy-method
和init-method一样,通过给destroy-method指定函数,就可以在bean销毁前执行指定的逻辑。

关于Aware

在设置属性阶段后,postProcessBeforeInitialization方法执行前,会执行很多Aware类型的接口,这种类型接口作用是加载资源到Spring容器中,Aware前面的名字就对应哪种资源,依次加载的是:

BeanNameAware
BeanClassLoaderAware
BeanFactoryAware
EnvironmentAware
ResourceLoaderAware
ApplicationEventPublisherAware
ApplicationContextAware
看到这里应该明白BeanFactory和ApplicationContext的区别了:
BeanFactoryAware之前加载的资源都是公共的。BeanFactoryAware后面加载的资源都是ApplicationContext独有的。

容器级扩展点(作用于所有bean):

BeanFactoryPostProcessor接口:
在循环初始化springbean之前,对BeanDefinition元数据做扩展处理
InstantiationAwareBeanPostProcessor接口: 在对象实例化前后扩展,作用于所有bean
BeanPostProcessor接口: 在对象初始化化前后扩展,作用于所有bean

(2)、Bean扩展点(作用于单个bean):

Aware接口: springBean实例化并且注入自定义属性之后 InitializingBean接口:
springBean初始化时,执行构造方法结束,并且属性赋初始化值结束之后执行 DiposableBean接口:
springBean销毁之前执行。

(3)、Bean自身的方法

包括了Bean本身调用的方法
通过配置文件中的init-method和destroy-method指定的方法(或者用注解的方式)
(4)、包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor,
CustomAutowireConfigurer等等非常有用的工厂后处理器接口的方法。
工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring bean生命周期详解 的相关文章

随机推荐

  • CSR867x — Speaker Equalizer曲线调试笔记

    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XX 作 者 文化人 XX 联系方式 或进群 471144274 XX 版权声明 原创文章 欢迎评论和转载 转载时能告诉我一声就最
  • 面试了一个 31岁的iOS开发者,思绪万千,30岁以上的程序员还有哪些出路?

    前言 之前HR给了我一份简历 刚看到简历的第一眼 31岁 让我有点意外 实际上 现在开发趋向于年轻化 大部分都是90后 95后 毕竟 软件开发不像硬件开发一样 年限越高 相对来说越吃香 31岁 iOS开发工程师 工作经历7年 5年左右都在外
  • vscode操作vue项目的相关步骤

    1 vscode下载安装https code visualstudio com vue插件的安装 1 vetur 该插件是vue文件基本语法的高亮插件 在插件窗口中输入vetur点击安装插件就行 装好后点击文件 gt 首选项 gt 设置 打
  • 合并有序的链表

    合并有序的链表 这里是升序 只是改变指针的方向O n 也是一道超经典的题目 完整实现如下 include
  • iOS自定义弹出窗口

    链接 https www jianshu com p b9bba621b295 先看示例 最终效果图 gif 首先搭建好基础界面 void viewDidLoad super viewDidLoad 设置背景色 self view back
  • [LeetCode]面试题 17.05. 字母与数字

    给定一个放有字母和数字的数组 找到最长的子数组 且包含的字母和数字的个数相同 返回该子数组 若存在多个最长子数组 返回左端点下标值最小的子数组 若不存在这样的数组 返回一个空数组 示例 1 输入 A 1 B C D 2 3 4 E 5 F
  • linux脚本中使用ftp,在shell脚本中使用ftp的方法分享

    有时 我们需要通过ftp传送文件到另一台机器 通常情况下 可以通过交互式的命令行来完成 但对于数据量较多的情况来讲 这样的操作会很烦琐 此时 可以写一段shell脚本 实现ftp文件的自动传输即可 可能的问题 在shell脚本中用FTP传输
  • python2.7 使用super关键词 报错 TypeError: must be type, not classobj 解决办法

    原创作品 允许转载 转载时请务必以超链接形式标明文章 原始出处 作者信息和本声明 否则将追究法律责任 http yeelone blog 51cto com 1476571 971591 今天遇到这个错误 Traceback most re
  • 在Oracle中创建新用户, 并且赋予该用户查看其他用户视图的权限

    本文由Markdown语法编辑器编辑完成 1 需求提出 在HIS与第三方系统进行集成时 某第三方系统需要访问HIS数据库的视图而非全部的数据库表 HIS的数据库为Oracle 因此需要在Oracle中在原有用户的基础上 再增加一个用户 该用
  • 什么是NetDevOps

    NetDevOps 是一种新兴的方法 它结合了 NetOps 和 DevOps 的流程 即将网络自动化集成到开发过程中 NetDevOps 的目标是将虚拟化 自动化和 API 集成到网络基础架构中 并实现开发和运营团队之间的无缝协作 开发运
  • npm 查看包的所有版本号

    这里以 vue cli 脚手架为例 npm view vue cli versions dengzemiao dengzemiaodeMacBook Pro uniapp npm view vue cli versions 3 0 0 al
  • gazebo仿真与ros控制器学习

    gazebo是一个功能强大的模拟器 尤其适合机器人的运动和控制模拟 但也存在很多bug 官方学习地址 http gazebosim org tutorials 包括了所有的教程 从初级中级到高级 也可以按照分类进行学习 这里主要讲与ros控
  • 80端口被占用时的终极解决方法

    摘要 之前在某次安全测试时 遇到一个80端口被占用的坑 将解决方法共享出来 使用netstat ano 命令查看是哪个进程正在占用80端口 之前在某次安全测试时 遇到一个80端口被占用的坑 将解决方法共享出来 使netstat ano 命令
  • linux nexus 启动失败_学习笔记之——nexus(四)记一次nexus故障

    一 故障描述 nexus服务器最初配置为4C8G 随着业务量的暴增 终于在某一天不堪重负 OOM了 排查后 增加内存到16G 再次启动 然后看似正常 然后却发生了诡异的事件 二 排查过程 问题一 查看日志 发现日志报错如下 报错日志1 经确
  • imx6ull视频监控项目,从kernel,buildroot,nginx,ffmpeg实现摄像头推流,vlc及web拉流

    写这一篇目的是记录自己使用buildroot 构建根文件系统 实现摄像头推流到VLC 及 web端 主要介绍的是 1 buildroot构建根文件系统 2 ffmpeg 及nginx 的配置 3 Linux内核构建 4 如何将摄像头的视频在
  • 软件项目管理课程授课教案

    序 软件项目管理概述 第一篇 软件项目初始 第1章 软件项目初始过程 第二篇 软件项目计划 第2章 软件项目范围计划 第3章 软件项目进度计划 第4章 软件项目成本计划 第5章 软件项目质量计划 第6章 软件项目人力资源计划 第7章 软件项
  • 灵创系统服务器,服装ERP-灵创软件-ICSCM供应链管理系统

    服装ERP 灵创软件 ICSCM供应链管理系统 一 产品概述 ICSCM供应链管理系统是基于品牌营运商和产品生产商之间紧密沟通 风险利润分担的大前提下诞生的一套全B S结构的系统 它是一种致力于在企业与供应商之间建立和维持长久的紧密合作伙伴
  • STM32系列(HAL库)——F103C8T6获取DHT11温湿度串口打印

    本文参考此篇博客并在其基础上进行了修改 STM32F103驱动DHT11温湿度传感器 STM32MXcube HAL 在此特别鸣谢原文博主 1 软件准备 1 编程平台 Keil5 2 CubeMX 3 XCOM 串口调试助手 2 硬件准备
  • Manifest.json文档说明

    Manifest json文件是5 移动App的配置文件 用于指定应用的显示名称 图标 应用入口文件地址及需要使用的设备权限等信息 是扩展的配置文件 指明了扩展的各种信息 一个manifest json格式如下 必须的字段3个 name M
  • Spring bean生命周期详解

    Spring Bean的完整生命周期从创建Spring容器开始 直到最终Spring容器销毁Bean 这其中包含了一系列关键点 Spring bean生命周期 四个阶段 Bean的实例化阶段 Bean的设置属性阶段 Bean的 初始化阶段