03Spring之Bean的生命周期(上)

bean的生命周期就是指,在spring中bean是如何创建,如何销毁的。

在这里插入图片描述

Bean的生成过程

1、生成BeanDefinition
首先Spring会进行包的扫描,将beanDefinitition存入Set集合。
spring扫描的过程大致如下。

  1. 首先,通过ResourcePatternResolver获得指定包路径下的所有 .class 文件(Spring源码中将 此文件包装成了Resource对象)
  2. 遍历每个Resource对象
  3. 利用MetadataReaderFactory解析Resource对象得到MetadataReader(用于获取类的元数据信息例如名字、实现了哪些接口等等)
  4. 利用MetadataReader进行excludeFilters和includeFilters,以及条件注解@Conditional的筛选
  5. 筛选通过后,基于metadataReader生成ScannedGenericBeanDefinition
  6. 再基于metadataReader判断是不是对应的类是不是接口或抽象类
  7. 如果筛选通过,那么就表示扫描到了一个Bean,将ScannedGenericBeanDefinition加入结果集

2、合并BeanDefinitition
什么是合并呢?举个例子。

<bean id="parent" class="com.zhouyu.service.Parent" scope="prototype"/>  
<bean id="child" class="com.zhouyu.service.Child" parent="parent"/>

如上述代码,bean之间可以通过parent属性进行继承,该例子中,child继承了parent,所以child类型也是prototype。所以这一步需要进行beandefinition的合并,得到child对应的beandefinition的完整属性。

3、类加载
BeanDefinition合并之后,就可以去创建Bean对象了,而创建Bean就必须实例化对象,而实例化就 必须先加载当前BeanDefinition所对应的class,在AbstractAutowireCapableBeanFactory类的 createBean()方法中,一开始就会调用:

Class<?> resolvedClass = resolveBeanClass(mbd, beanName);

以上这行代码就是加载类的代码,点进去实现如下。

if (mbd.hasBeanClass()) {   
	 return mbd.getBeanClass(); 
  }  
if (System.getSecurityManager() != null) 
  {   
	 return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>) ()>      doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());   
  }  
  else {    
 	 return doResolveBeanClass(mbd, typesToMatch); 
  } 

如果beanClass属性的类型是Class,那么就直接返回,如果不是,则会根据类名进行加载 (doResolveBeanClass方法所做的事情)
会利用BeanFactory所设置的类加载器来加载类,如果没有设置,则默认使用 **ClassUtils.getDefaultClassLoader()**所返回的类加载器来加载。
那么它返回什么呢?

  1. 优先返回当前线程中的ClassLoader
  2. 线程中类加载器为null的情况下,返回ClassUtils类的类加载器
  3. 如果ClassUtils类的类加载器为空,那么则表示是Bootstrap类加载器加载的ClassUtils类,那么 则返回系统类加载器。

4、实例化前
在Spring中,实例化对象之前,Spring提供了一个扩展点,允许用户来控制是否在某个或某些Bean 实例化之前做一些启动动作。这个扩展点叫 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()。比如

@Component  
public class ZhouyuBeanPostProcessor implements InstantiationAwareBeanPostProcessor { 
  @Override    
  public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName)  throws BeansException {      
  if ("userService".equals(beanName)) { 
   System.out.println("实例化前");      
  	 }      
  	 return null;   
  } 
} 

如上代码会导致,在userService这个Bean实例化前,会进行打印。
值得注意的是,postProcessBeforeInstantiation()是有返回值的,如果这么实现:

userService这个Bean,在实例化前会直接返回一个由我们所定义的UserService对象。如果是这样, 表示不需要Spring来实例化了,并且后续的Spring依赖注入也不会进行了,会跳过一些步骤,直接执 行初始化后这一步。

5、实例化
5.1 Supplier创建对象
5.2 工厂方法创建对象
5.3 推断构造方法

6. BeanDefinition的后置处理

Bean对象实例化出来之后,接下来就应该给对象的属性赋值了。在真正给属性赋值之前,Spring又 提供了一个扩展点 MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(),可以对此时的 BeanDefinition进行加工,大致实现跟上文介绍的那个扩展点类似,这里就不重复说明了。

7、实例化后
在处理完BeanDefinition后,Spring又设计了一个扩展点: InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()

8、自动注入
这里的自动注入指的是Spring的自动注入,后续会说到。

9、处理属性

这个步骤中,就会处理@Autowired、@Resource、@Value等注解,也是通过 **InstantiationAwareBeanPostProcessor.postProcessProperties()**扩展点来实现的

10、执行Aware

  1. BeanNameAware:回传beanName给bean对象。
  2. BeanClassLoaderAware:回传classLoader给bean对象。
  3. BeanFactoryAware:回传beanFactory给对象。

11、初始化前
初始化前,也是Spring提供的一个扩展点:
BeanPostProcessor.postProcessBeforeInitialization()

12、初始化

  1. 查看当前Bean对象是否实现了InitializingBean接口,如果实现了就调用其afterPropertiesSet() 方法
  2. 执行BeanDefinition中指定的初始化方法

13、初始化后
这是Bean创建生命周期中的最后一个步骤,也是Spring提供的一个扩展点: BeanPostProcessor.postProcessAfterInitialization(),可以在这个步骤中,对Bean最终进行处理,Spring中的AOP就是基于初始化后实现的,初始化后返 回的对象才是最终的Bean对象。

—参考周瑜大佬笔记

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 对于SpringBean生命周期Spring在容器中有5个生命周期阶段,它们分别是:实例化、属性设置、初始化、销毁以及单例实例化,每个阶段的bean都会触发一个对应的回调事件,让开发者能够在每个阶段做一些额外的处理。 ### 回答2: SpringBean 生命周期包括以下几个阶段: 1. Bean 实例化:Spring 在启动时会通过反射机制实例化 Bean。这是 Bean 生命周期的开始阶段。 2. Bean 属性设置:Spring 在实例化 Bean 后,会根据配置文件或注解等方式,将属性值注入到 Bean 中。 3. Bean 初始化前置处理:如果 Bean 实现了 InitializingBean 接口,那么 Spring 会在属性设置完成后调用 Bean 的 afterPropertiesSet() 方法进行初始化前的处理。 4. Bean 初始化后置处理:如果 Bean 配置了 init-method 方法,或者在配置文件中通过 init-method 属性指定了初始化方法,那么 Spring 会在初始化前置处理完成后调用该方法。 5. Bean 使用阶段:在初始化完成后,Bean 就可以被应用程序使用了。 6. Bean 销毁前置处理:如果 Bean 实现了 DisposableBean 接口,那么在关闭应用程序或手动销毁 Bean 时,Spring 会先调用 Bean 的 destroy() 方法进行销毁前的处理。 7. Bean 销毁后置处理:如果 Bean 配置了 destroy-method 方法,或者在配置文件中通过 destroy-method 属性指定了销毁方法,那么 Spring 会在销毁前置处理完成后调用该方法。 在整个 Bean 生命周期中,开发人员可以通过实现 InitializingBean 和 DisposableBean 接口,或者在配置文件中指定 init-method 和 destroy-method 方法,来自定义 Bean 的初始化和销毁过程,并在这些过程中进行一些特定的操作。 ### 回答3: SpringBean生命周期可以分为以下阶段: 1. 实例化:Spring通过Bean定义创建Bean的实例。这可以通过构造函数实例化,或者通过工厂方法来实现。 2. 属性赋值:SpringBean的属性值注入到Bean的实例。这可以通过依赖注入(DI)方式进行,也可以通过配置文件或注解来实现。 3. 初始化:在Bean实例化和属性赋值之后,Spring会调用Bean的初始化方法。这可以通过实现InitializingBean接口的afterPropertiesSet()方法,或者使用@PostConstruct注解来实现。 4. 使用:在初始化完成之后,Bean可以被使用,执行业务逻辑。 5. 销毁:当Bean不再需要时,Spring会调用Bean的销毁方法。这可以通过实现DisposableBean接口的destroy()方法,或者使用@PreDestroy注解来实现。 需要注意的是,在Bean的生命周期中,可以通过配置文件或注解来控制Bean的创建和销毁方式。 总的来说,SpringBean生命周期包括实例化、属性赋值、初始化、使用和销毁这几个阶段。通过控制Bean的生命周期,我们可以在合适的时机执行一些特定的操作,如初始化资源、释放资源等。这样可以有效地管理Bean的生命周期,提高系统的性能和可维护性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我不认识CBW

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值