spring bean的生命周期是怎样的,代码示例
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring bean的生命周期是怎样的,代码示例相关的知识,希望对你有一定的参考价值。
参考技术A Spring中bean的生命周期管理可以在xml配置文件(一般叫bean.xml或ApplicationContext.xml)中通过scope属性进行控制。当scope属性默认的为singleton(单例),这个时候bean是在spring容器启动的时候进行加载和实例化并且是单实例的;当你将scope属性改为prototype的时候,这种情况下bean将在bean被调用时实例化并且每次调用生成一个bean的实例。(request,session,global session属性将在web变成是再学习)lazy-init属性默认为false,即在spring容器启动时加载并实例化配置文件中定义的所有 bean,当然当我们指定为true的时候,bean将在程序调用的时候才初始化,该属性定义在<bean>中。当你希望每个bean都拥有相同的lazy-init属性,这时你可以在<beans>中定义global-lazy-init属性进行指定。
同时可以指定bean的初始化方法init-method属性和销毁方法destroy-method属性。
作用域范围是单例的bean是在实例化容器的时候就实例化。
作用域范围是prototype的bean是在getBean的时候被实例化的。
作用与范围是单实例并且lazy-init="true",是在getBean的时候被实例化的。
也可以指定beans节点的属性default-lazy-init=true
lazy-init的缺点是不能再启动时发现实例化的错误,只能在运行期发现,这点是我们不太希望看到的
如果在生成bean时需要对某些资源进行初始化,可以指定init-method="init",方法名指定为类里面的方法名。此方法是在实例化过后执行。如果在bean被销毁前要关闭一些资源,可以指定destroy-method="destroy"
需要调用spring容器的close方法进行关闭才能执行销毁方法,与前面代码有一定不同。
AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
ctx.close();
Bean的生命周期:
(1)实例化(必须的)构造函数构造对象
(2)装配(可选的)为属性赋值
(3)回调(可选的)(容器-控制类和组件-回调类)
(4)初始化(init-method=" ")本回答被提问者和网友采纳
Spring之bean的生命周期
Spring之bean的生命周期
前言
Spring作为当前Java最流行、最强大的轻量级框架,受到了大多数开发者的热烈欢迎。相必大多数小伙伴在面试的时候都会问道Spring中bean的生命周期是怎样的。所以准确的了解Spring Bean的生命周期也成为了必备知识点。
狭义层面的bean的生命周期详解
在我们学习Spring的bean的生命周期的时候,我们要知道什么是bean。
bean的定义:
被称作 bean 的对象是构成应用程序的支柱也是由 Spring IoC 容器管理的。bean 是一个被实例化,组装,并通过 Spring IoC 容器所管理的对象。这些 bean 是由用容器提供的配置元数据创建的,例如,
<bean id="helloWorld" class="com.tutorialspoint.HelloWorld">
<property name="message" value="Hello World!"/>
</bean>
在 XML 的表单中的 定义。
bean 定义包含称为配置元数据的信息,下述容器也需要知道配置元数据:
-
如何创建一个 bean
-
bean 的生命周期的详细信息
- bean 的依赖关系
上述所有的配置元数据转换成一组构成每个 bean 定义的下列属性。
属性 | 描述 |
---|---|
class | 这个属性是强制性的,并且指定用来创建 bean 的 bean 类。 |
name | 这个属性指定唯一的 bean 标识符。在基于 XML 的配置元数据中,你可以使用 ID 和/或 name 属性来指定 bean 标识符。 |
scope | 这个属性指定由特定的 bean 定义创建的对象的作用域,它将会在 bean 作用域的章节中进行讨论。 |
constructor-arg | 它是用来注入依赖关系的,并会在接下来的章节中进行讨论。 |
properties | 它是用来注入依赖关系的,并会在接下来的章节中进行讨论。 |
autowiring mode | 它是用来注入依赖关系的,并会在接下来的章节中进行讨论。 |
lazy-initialization mode | 延迟初始化的 bean 告诉 IoC 容器在它第一次被请求时,而不是在启动时去创建一个 bean 实例。 |
initialization 方法 | 在 bean 的所有必需的属性被容器设置之后,调用回调方法。它将会在 bean 的生命周期章节中进行讨论。 |
destruction 方法 | 当包含该 bean 的容器被销毁时,使用回调方法。它将会在 bean 的生命周期章节中进行讨论。 |
bean与常规对象的区别是什么呢?
@Component
public class UserService {
}
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
//在Spring容器中获取bean
UserService userService = applicationContext.getBean(UserService.class);
//new一个UserService对象
UserService userService1 = new UserService();
}
通过上述代码我们发现bean对象与我们new出来的对象是没有区别的。下面我们来对比下面代码看有何不同。
@Component
public class User {
}
@Component
public class UserService {
@Autowired
private User user;
}
public class TestSpringBean {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = applicationContext.getBean(UserService.class);
UserService userService1 = new UserService();
}
}
我们可以发现在上述代码中,通过Spring容器获取到的UserService的bean对象中的User属性是已经有值的,也就是通常说的Spring的依赖注入。而我们new出来的UserService对象中的User属性是没有值的。当然不仅仅这一个区别,我们知道在bean的生命周期中Spring做了很多事情的,继续分析。
Bean 的生命周期
理解 Spring bean 的生命周期很容易。当一个 bean 被实例化时,它可能需要执行一些初始化使它转换成可用状态。同样,当 bean 不再需要,并且从容器中移除时,可能需要做一些清除工作。为了定义安装和销毁一个 bean,我们只要声明带有 init-method 和/或 destroy-method 参数的 。init-method 属性指定一个方法,在实例化 bean 时,立即调用该方法。同样,destroy-method 指定一个方法,只有从容器中移除 bean 之后,才能调用该方法。
Bean的生命周期可以表达为:Bean的定义——Bean的初始化——Bean的使用——Bean的销毁
知识点:在单例模式下,在Spring启动的时候就会生成bean对象。而在原型模式下,才会在getBean的时候生成bean对象。
下面我们通过源码来分析bean的生命周期:详情请参考:https://www.cnblogs.com/darope/p/13917264.html
1.我们首先点开AnnotationConfigApplicationContext。
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
//初始化AnnotatedBeanDeinitionReader和classPathBeanDefinitionScanner
//AnnotatedBeanDeinitionReader会生成5个基础的BeanDefinition
//ClassPathBeanDefinitionScanner
this();
//先把AppConfig类注册位一个AnnotatedGenericBeanDefinition
register(componentClasses);
//到此为止AnnotationConfigApplicationContext有6个BeanDefinition
refresh();
}
2.Spring容器创建之后,会调用它的refresh方法刷新Spring应用的上下文。
首先整体查看AbstractApplicationContext的refresh源码
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//刷新前的预处理;
prepareRefresh();
//获取BeanFactory;默认实现是DefaultListableBeanFactory,在创建容器的时候创建的
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//BeanFactory的预准备工作(BeanFactory进行一些设置,比如context的类加载器,BeanPostProcessor和XXXAware自动装配等)
prepareBeanFactory(beanFactory);
try {
//BeanFactory准备工作完成后进行的后置处理工作
postProcessBeanFactory(beanFactory);
//执行BeanFactoryPostProcessor的方法;
invokeBeanFactoryPostProcessors(beanFactory);
//注册BeanPostProcessor(Bean的后置处理器),在创建bean的前后等执行
registerBeanPostProcessors(beanFactory);
//初始化MessageSource组件(做国际化功能;消息绑定,消息解析);
initMessageSource();
//初始化事件派发器
initApplicationEventMulticaster();
//子类重写这个方法,在容器刷新的时候可以自定义逻辑;如创建Tomcat,Jetty等WEB服务器
onRefresh();
//注册应用的监听器。就是注册实现了ApplicationListener接口的监听器bean,这些监听器是注册到ApplicationEventMulticaster中的
registerListeners();
//初始化所有剩下的非懒加载的单例bean
finishBeanFactoryInitialization(beanFactory);
//完成context的刷新。主要是调用LifecycleProcessor的onRefresh()方法,并且发布事件(ContextRefreshedEvent)
finishRefresh();
}
......
}
3.在refresh方法其中有一行代码,调用了finishBeanFactoryInitialization(beanFactory)。在这一步之前,已经完成了BeanFactory对象初始化、xml配置文件解析成BeanDefinition、BeanPostProcessor初始化与注册等操作。而在完成BeanFactory初始化之时,会初始化容器内所有单例非懒加载对象,供后续业务逻辑进行依赖注入等使用,具体实现在finishBeanFactoryInitialization(beanFactory)内部的最后一行代码。【懒加载运用:@lazy注解加载到要进行懒加载的类上就能实现】。
该方法会实例化所有剩余的非懒加载单例 bean。除了一些内部的 bean、实现了 BeanFactoryPostProcessor 接口的 bean、实现了 BeanPostProcessor 接口的 bean,其他的非懒加载单例 bean 都会在这个方法中被实例化,并且 BeanPostProcessor 的触发也是在这个方法中。
/**
* Finish the initialization of this context's bean factory,
* initializing all remaining singleton beans.
*/
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
/**
* 把类型转化操作,设置到当前的beanFactory里面去
**/
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
/**
* 判断当前的beanFactory有没有内置的值处理器
**/
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
/**
* 织入Aware
**/
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
// 设置类加载器
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
/**
* 冻结:某些bean不需要进行修改操作了,放入
**/
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
/**
* 实例化所有非懒加载的实例对象(重要)
**/
beanFactory.preInstantiateSingletons();
}
4.具体的preInstantiateSingletons实现如下: preInstantiateSingletons方法的意思就是实例化所有剩余(非懒加载)单例对象
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isInfoEnabled()) {
this.logger.info("Pre-instantiating singletons in " + this);
}
// 获取容器内加载的所有BeanDefinition
List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
// 遍历初始化所有非懒加载单例Bean
for (String beanName : beanNames) {
// Bean定义公共的抽象类是AbstractBeanDefinition,普通的Bean在Spring加载Bean定义的时候,实例化出来的是GenericBeanDefinition
// 而Spring上下文包括实例化所有Bean用的AbstractBeanDefinition是RootBeanDefinition
// 这时候就使用getMergedLocalBeanDefinition方法做了一次转化,将非RootBeanDefinition转换为RootBeanDefinition以供后续操作。
// 注意如果当前BeanDefinition存在父BeanDefinition,会基于父BeanDefinition生成一个RootBeanDefinition,然后再将调用OverrideFrom子BeanDefinition的相关属性覆写进去。
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 如果Bean不是抽象的,是单例的,不是懒加载的,则开始创建单例对象通过调用getBean(beanName)方法初始化
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 判断当前Bean是否实现了FactoryBean接口,如果实现了,判断是否要立即初始化
// 判断是否需要立即初始化,根据Bean是否实现了SmartFactoryBean并且重写的内部方法isEagerInit放回true
if (isFactoryBean(beanName)) {
//根据beanname创建一个factorybean对象
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
//eager:急切地意思,立马初始化
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
//根据beanName去创建一个bean
if (isEagerInit) {
getBean(beanName);
}
}
else {
getBean(beanName);
}
}
}
}
5.具体getBean方法实现如下所示:
// 具体getBean函数实现如下所示:
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
/*
进一步调用了如下方法,其中有参数:
requiredType=null: 一般情况用不到,如果获取到的字符串,但requiredType是Integer,会在最后进行类型转换。
args=null: 在获取prototype对象时传入,用来初始化原型对象
typeCheckOnly=false: 如果为false,会将Bean标志为已创建,记录在alreadyCreated变量中。
*/
//真正实现向IOC容器获取Bean的功能,也是触发依赖注入功能的地方
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
//提取对应的beanName
//1.根据指定的名称获取被管理Bean的名称,剥离指定名称中对容器的相关依赖
//2.如果指定的是别名,将别名转换为规范的Bean名称
final String beanName = transformedBeanName(name);
Object bean;
/**
* 检查缓存中或者实例工厂中是否有对应的实例(直接尝试从缓存中获取singletonFactories中的ObjectFactory获取实例)
* 在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖
* spring创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光
* 也就是将ObjectFactory加入到缓存中,一单下一个bean创建时需要依赖这个bean则直接使用ObjectFactory
*
*
*/
//先从缓存中取是否已经有被创建过的单态类型的Bean
//对于单例模式的Bean整个IOC容器中只创建一次,不需要重复创建
Object sharedInstance = getSingleton(beanName);
//IOC容器创建单例模式Bean实例对象
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
//如果指定名称的Bean在容器中已有单例模式的Bean被创建
//直接返回已经创建的Bean
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
//获取给定Bean的实例对象,主要是完成FactoryBean的相关处理
//注意:BeanFactory是管理容器中Bean的工厂,而FactoryBean是创建创建对象的工厂Bean,两者之间有区别
//返回对应的实例,有时候存在诸如BeanFactory的情况并不是直接返回实例本身而是返回指定方法返回的实例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
/**
* 只有在单例情况下才会尝试解决循环依赖,
* 原型模式下如果存在:A中有B的属性,B中有A的属性,那么当依赖注入的时候,
* 就会产生当A还未创建完的时候因为对于B的创建再次返回创建A,造成循环依赖,也就是下面的情况
*/
//缓存没有正在创建的单例模式Bean
//缓存中已经有已经创建的原型模式Bean
//但是由于循环引用的问题导致实例化对象失败
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
//对IOC容器中是否存在指定名称的BeanDefinition进行检查,首先检查是否能在当前的BeanFactory中获取的所需要的Bean,如果不能则委托当前容器的父级容器去查找,如果还是找不到则沿着容器的继承体系向父级容器查找
BeanFactory parentBeanFactory = getParentBeanFactory();
//当前容器的父级容器存在,且当前容器中不存在指定名称的Bean
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
//解析指定Bean名称的原始名称
String nameToLookup = originalBeanName(name);
//递归到BeanFactory中寻找
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
//委派父级容器根据指定名称和显式的参数查找
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
//委派父级容器根据指定名称和类型查找
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
//创建的Bean是否需要进行类型验证,一般不需要
if (!typeCheckOnly) {
//向容器标记指定的Bean已经被创建
markBeanAsCreated(beanName);
}
try {
/**
* 将存储XML配置文件的GernericBeanDefinition转换为RootBeanDefinition。
* 如果指定BeanName是子Bean的话同时会合并父类的相关属性
*/
//根据指定Bean名称获取其父级的Bean定义
//主要解决Bean继承时子类合并父类公共属性问题
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
//获取当前Bean所有依赖Bean的名称
String[] dependsOn = mbd.getDependsOn();
//如果当前Bean有依赖Bean,则需要递归实例化依赖的bean
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
//先去生成所依赖的bean
getBean(dep);
//缓存依赖调用
registerDependentBean(dep, beanName);
}
}
// Create bean instance.
//创建单例模式Bean的实例对象,
//实例化以来的bean后便可以实例化mbd本身了
if (mbd.isSingleton()) {
//这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象
sharedInstance = getSingleton(beanName, () -> {
try {
//创建一个指定Bean实例对象,如果有父级继承,则合并子类和父类的定义
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
//显式地从容器单例模式Bean缓存中清除实例对象
destroySingleton(beanName);
throw ex;
}
});
//获取给定Bean的实例对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//IOC容器创建原型模式Bean实例对象
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
//原型模式(Prototype)是每次都会创建一个新的对象
Object prototypeInstance = null;
try {
//回调beforePrototypeCreation方法,默认的功能是注册当前创建的原型对象
beforePrototypeCreation(beanName);
//创建指定Bean对象实例
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
//回调afterPrototypeCreation方法,默认的功能告诉IOC容器指定Bean的原型对象不再创建
afterPrototypeCreation(beanName);
}
//获取给定Bean的实例对象
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
//要创建的Bean既不是单例模式,也不是原型模式,则根据Bean定义资源中
//配置的生命周期范围,选择实例化Bean的合适方法,这种在Web应用程序中
//比较常用,如:request、session、application等生命周期
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
//Bean定义资源中没有配置生命周期范围,则Bean定义不合法
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
//这里又使用了一个匿名内部类,获取一个指定生命周期范围的实例
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
//获取给定Bean的实例对象
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
//对创建的Bean实例对象进行类型检查
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
6.getSingleton的方法的实现在父类DefaultSingletonBeanRegistry中。
// 从单例池中获取bean:
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "'beanName' must not be null");
synchronized (this.singletonObjects) {
//双重判定从缓存中获取
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while the singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
// 创建前置检查,默认实现是记录当前beanName正在注册中
beforeSingletonCreation(beanName);
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<Exception>();
}
try {
// 调用签名定义的内部类进行创建,内部调用了createBean(String beanName, RootBeanDefinition mbd, Object[] args)
singletonObject = singletonFactory.getObject();
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// 创建前置检查,默认实现是移除当前beanName正在注册状态的记录
afterSingletonCreation(beanName);
}
addSingleton(beanName, singletonObject);
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
}
7.createBean方法,去创建一个bean
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
//确保此时bean类已经被解析,并且克隆的bean定义一个动态解析类不能存储在共享合并bean定义。
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
//实例化之前
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
//创建bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
8.resolveBeforeInstantiation方法,表示在实例化bean之前要做一些事情。Spring中提供了 InstantiationAwareBeanPostProcessor这个接口, 我们开发者可以通过重写postProcessBeforeInstantiation方法去对bean做一些操作。
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 (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
return null;
}
9.doCreateBean方法。表示正式创建一个bean对象。在doCreateBean方法中包括填充属性这一步骤,这一步骤是在实例化之后【 调用接口InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation】,然后进行初始化(initializeBean)。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
// 如果定义的是单例模式,就先从缓存中清除
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
//实例化
// 如果 instanceWrapper 为空,那就 创建对应的beanInstance,具体方法在下面小节分析
if (instanceWrapper == null) {
//创建bean实例,推断构造方法
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//原始对象
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
// 将 解析类型 设置 为 beanType
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
// 使用后置处理器 对其进行处理
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 这里主要是 MergedBeanDefinitionPostProcessor
//对@Autowire,@Value等这些注解进行处理, 相关的可以
// 参考AutowiredAnnotationBeanPostProcessor 相关逻辑
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
/**是否需要提前曝光: 单例& 允许循环依赖 & 当前bean正在创建中, 检查循环依赖
这里主要是调用 方法addSingletonFactory ,往缓存singletonFactories里面 放入一个 ObjectFactory
当其他的bean 对该bean 有依赖时,可以提前获取到
getEarlyBeanReference方法就是获取一个引用, 里面主要是
调用了 SmartInstantiationAwareBeanPostProcessor,
的 getEarlyBeanReference 方法,以便解决循环依赖问题, 这里 一般都是bean 本身,
在 AOP时 是代理
**/
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// 为避免后期循环依赖,可以在 bean 初始化完成前将创建实例的 objectFactory加入缓存
// 对bean 再一次依赖引用,主要应用SmartInstantiationAwareBeanPostProcessor
// 其中我们熟悉的AOP就是在这里将advice 动态织入,若没有直接返回bean
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
// 下面就是初始化实例了
try {
//填充属性
// 对bean进行填充,将各个属性值注入,其中可能存在依赖于其他bean的属性,会递归初始化
populateBean(beanName, mbd, instanceWrapper);
//进一步初始化Bean
//注入 Aware 相关的对象
// 调用 后置处理器 BeanPostProcessor 里面的postProcessBeforeInitialization方法
// 调用 initialzingBean,调用实现的 afterPropertiesSet()
// 调用 init-mothod,调用相应的init方法
// 调用 后置处理器 BeanPostProcessor 里面的调用实现的postProcessAfterInitialization方法
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
earlySingletonReference 只有在检测到有循环依赖的情况下才会不为空
if (earlySingletonReference != null) {
//如果exposedObject 没有在初始化方法中被改变,也就是没有被增强
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
// 检查依赖
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
/**
因为 bean 创建后其所依赖的bean一定是已经创建,
actualDependentBeans 不为空则表示 当前bean 创建后其依赖的bean 却没有全部创建,
也就是说存在依赖
*/
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
// 注册到 disposableBeans 里面,以便在销毁bean 的时候 可以运行指定的相关业务
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
10.initializeBean方法。初始化bean包括1.执行Aware。2.初始化之前。3.初始化。4.初始化之后四个步骤。
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
//执行Aware
//调用所有BeanNameAware、BeanClassLoaderAware、BeanFactoryAware接口方法
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//初始化之前
//执行初始化之前的 前置操作 https://blog.csdn.net/u010634066/article/details/80291728
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//调用初始化方法
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()) {
//初始化之后
//执行初始化之后的 后置操作 https://blog.csdn.net/u010634066/article/details/80291728
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
10.1.invokeAwareMethods方法。该方法的起到一个回调的作用。
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);
}
}
}
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
//去遍历每个bean对象的初始化之前的方法
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
10.3 invokeInitMethods方法。初始化bean方法
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
//判断当前的bean有没有实现InitializingBean这个接口
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接口,则执行afterPropertiesSet方法
((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);
}
}
}
10.4 applyBeanPostProcessorsAfterInitialization方法。初始化之后
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
至此,完成了单例非懒加载Bean初始化流程分析,实际上,几乎所有的Bean都通过getBean方法进行获取,在获取过程中,会先尝试从缓存中获取,在获取失败后,则会调用createBean方法进行创建。
总结:
过程:class---->BeanDefinition---->BeanFactoryPostProcessor---->new 对象----->填充属性---->Aware织入---->初始化---->AOP---->放入单例池---->bean对象
实例化
1.实例化前:InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
2.实例化中:推断构造,new 对象
3.实例化后:InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation 填充属性
初始化
0.Aware
1.初始化前:BeanPostProcessor.postProcessBeforeInitialization
2.初始化中:InitializingBean
3.初始化后:AOP代理对象 BeanPostProcessAfterInitialization
广义层面的bean的生命周期详解
Spring后置处理器详解
请参考:https://blog.csdn.net/weixin_43403173/article/details/103490082
Bean的Scope有几种
singleton: 在Spring的IoC容器中只存在一个对象实例,所有该对象的引用都共享这个实例。Spring 容器只会创建该bean定义的唯一实例,这个实例会被保存到缓存中,并且对该bean的所有后续请求和引用都将返回该缓存中的对象实例,一般情况下,无状态的bean使用该scope。
prototype:每次对该bean的请求都会创建一个新的实例,一般情况下,有状态的bean使用该scope。
request:每次http请求将会有各自的bean实例,类似于prototype。
session:在一个http session中,一个bean定义对应一个bean实例。
global session:在一个全局的http session中,一个bean定义对应一个bean实例。典型情况下,仅在使用portlet context的时候有效。
文章中所涉及到的面试题
1.SpringBean的生命周期详解
2.BeanPostProcessor和BeanFactoryPostProcess的区别和联系
3.BeanFactory和ApplicationContext的区别和联系
4.BeanFactory和FactoryBean的区别和联系
5.FactoryBean的典型应用场景
以上是关于spring bean的生命周期是怎样的,代码示例的主要内容,如果未能解决你的问题,请参考以下文章