Spring中Bean的生命周期使用解析

作者:技术-刘腾飞 时间:2021-09-06 23:06:54 

Bean的生命周期

Spring中Bean的生命周期使用解析

Spring中Bean的生命周期使用解析

解释

(1)BeanFactoryPostProcessor的postProcessorBeanFactory()方法:若某个IoC容器内添加了实现了BeanFactoryPostProcessor接口的实现类Bean,那么在该容器中实例化任何其他Bean之前可以回调该Bean中的postPrcessorBeanFactory()方法来对Bean的配置元数据进行更改,比如从XML配置文件中获取到的配置信息。

(2)Bean的实例化:Bean的实例化是使用反射实现的。

(3)Bean属性注入:Bean实例化完成后,利用反射技术实现属性及依赖Bean的注入。

(4)BeanNameAware的setBeanName()方法:如果某个Bean实现了BeanNameAware接口,那么Spring将会将Bean实例的ID传递给setBeanName()方法,在Bean类中新增一个beanName字段,并实现setBeanName()方法。

(5)BeanFactoryAware的setBeanFactory()方法:如果某个Bean实现了BeanFactoryAware接口,那么Spring将会将创建Bean的BeanFactory传递给setBeanFactory()方法,在Bean类中新增了一个beanFactory字段用来保存BeanFactory的值,并实现setBeanFactory()方法。

(6)ApplicationContextAware的setApplicationContext()方法:如果某个Bean实现了ApplicationContextAware接口,那么Spring将会将该Bean所在的上下文环境ApplicationContext传递给setApplicationContext()方法,在Bean类中新增一个ApplicationContext字段用来保存ApplicationContext的值,并实现setApplicationContext()方法。

(7)BeanPostProcessor预初始化方法:如果某个IoC容器中增加的实现BeanPostProcessor接口的实现类Bean,那么在该容器中实例化Bean之后,执行初始化之前会调用BeanPostProcessor中的postProcessBeforeInitialization()方法执行预初始化处理。

(8)InitializingBean的afterPropertiesSet()方法:如果Bean实现了InitializingBean接口,那么Bean在实例化完成后将会执行接口中的afterPropertiesSet()方法来进行初始化。

(9)自定义的inti-method指定的方法:如果配置文件中使用init-method属性指定了初始化方法,那么Bean在实例化完成后将会调用该属性指定的初始化方法进行Bean的初始化。

(10)BeanPostProcessor初始化后方法:如果某个IoC容器中增加的实现BeanPostProcessor接口的实现类Bean,那么在该容器中实例化Bean之后并且完成初始化调用后执行该接口中的postProcessorAfterInitialization()方法进行初始化后处理。

(11)使用Bean:此时有关Bean的所有准备工作均已完成,Bean可以被程序使用了,它们将会一直驻留在应用上下文中,直到该上下文环境被销毁。

(12)DisposableBean的destory()方法:如果Bean实现了DisposableBean接口,Spring将会在Bean实例销毁之前调用该接口的destory()方法,来完成一些销毁之前的处理工作。

(13)自定义的destory-method指定的方法:如果在配置文件中使用destory-method指定了销毁方法,那么在Bean实例销毁之前会调用该指定的方法完成一些销毁之前的处理工作。

注意:

1、BeanFactoryPostProcessor接口与BeanPostProcessor接口的作用范围是整个上下文环境中,使用方法是单独新增一个类来实现这些接口,那么在处理其他Bean的某些时刻就会回调响应的接口中的方法。

2、BeanNameAware、BeanFactoryAware、ApplicationContextAware的作用范围的Bean范围,即仅仅对实现了该接口的指定Bean有效,所有其使用方法是在要使用该功能的Bean自己来实现该接口。

3、第8点与第9点所述的两个初始化方法作用是一样的,我们完全可以使用其中的一种即可,一般情况我们使用第9点所述的方式,尽量少的去来Bean中实现某些接口,保持其独立性,低耦合性,尽量不要与Spring代码耦合在一起。第12和第13也是如此。

4、 在BeaFactoryAware's setBeanFactory()和Pre-initialization BeanPostProcessor之间还应该有一步:调用ApplicationContextAware的setApplicationContext()方法。
可以看到Bean生命周期要经历很多阶段,但这些阶段大部分都是可选的。例如,某个Bean如果实现了BeanFactoryAware接口的setBeanFactory方法,那么该Bean的生命就会经历这个阶段,如果不实现则没有。

使用


public class Book implements BeanNameAware, BeanFactoryAware,
   ApplicationContextAware, InitializingBean, DisposableBean {
 private String bookName;
 public Book(){
   System.out.println("Book Initializing ");
 }
 @Override
 public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
   System.out.println("Book.setBeanFactory invoke");
 }
 @Override
 public void setBeanName(String name) {
   System.out.println("Book.setBeanName invoke");
 }
 @Override
 public void destroy() throws Exception {
   System.out.println("Book.destory invoke");
 }
 @Override
 public void afterPropertiesSet() throws Exception {
   System.out.println("Book.afterPropertiesSet invoke");
 }
 @Override
 public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
   System.out.println("Book.setApplicationContext invoke");
 }
 public String getBookName() {
   return bookName;
 }
 public void setBookName(String bookName) {
   this.bookName = bookName;
   System.out.println("setBookName: Book name has set.");
 }
 public void myPostConstruct(){
   System.out.println("Book.myPostConstruct invoke");
 }
 // 自定义初始化方法
 @PostConstruct
 public void springPostConstruct(){
   System.out.println("@PostConstruct");
 }
 public void myPreDestory(){
   System.out.println("Book.myPreDestory invoke");
   System.out.println("---------------destroy-----------------");
 }
 // 自定义销毁方法
 @PreDestroy
 public void springPreDestory(){
   System.out.println("@PreDestory");
 }
 @Override
 protected void finalize() throws Throwable {
   System.out.println("------inside finalize-----");
 }
}
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
 public MyBeanFactoryPostProcessor() {
   super();
   System.out.println("这是BeanFactoryPostProcessor实现类构造器!!");
 }
 @Override
 public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0)
     throws BeansException {
   System.out
       .println("BeanFactoryPostProcessor调用postProcessBeanFactory方法");
   BeanDefinition bd = arg0.getBeanDefinition("book");
   bd.getPropertyValues().addPropertyValue("bookName", "ddd");
 }
}
// 通过注入调用
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
 @Override
 public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
   if(bean instanceof Book){
     System.out.println("MyBeanPostProcessor.postProcessBeforeInitialization");
   }
   return bean;
 }
 @Override
 public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
   if(bean instanceof Book){
     System.out.println("MyBeanPostProcessor.postProcessAfterInitialization");
   }
   return bean;
 }
}

// ClassPathXmlApplicationContext 这个类实例化就会调用这个类
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
 public MyBeanFactoryPostProcessor() {
   super();
   System.out.println("这是BeanFactoryPostProcessor实现类构造器!!");
 }
 @Override
 public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0)
     throws BeansException {
   System.out
       .println("BeanFactoryPostProcessor调用postProcessBeanFactory方法");
   BeanDefinition bd = arg0.getBeanDefinition("book");
   bd.getPropertyValues().addPropertyValue("bookName", "ddd");
 }
}
// InstantiationAwareBeanPostProcessor 接口本质是BeanPostProcessor的子接口,一般我们继承Spring为其提供的适配器类InstantiationAwareBeanPostProcessor Adapter来使用它,如下:
public class MyInstantiationAwareBeanPostProcessor extends
   InstantiationAwareBeanPostProcessorAdapter {
 public MyInstantiationAwareBeanPostProcessor() {
   super();
   System.out
       .println("这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!");
 }
 // 接口方法、实例化Bean之前调用
 @Override
 public Object postProcessBeforeInstantiation(Class beanClass,
                        String beanName) throws BeansException {
   System.out
       .println("InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法");
   return null;
 }
// 接口方法、实例化Bean之后调用
 @Override
 public Object postProcessAfterInitialization(Object bean, String beanName)
     throws BeansException {
   System.out
       .println("InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法");
   return bean;
 }
// 接口方法、设置某个属性时调用
 @Override
 public PropertyValues postProcessPropertyValues(PropertyValues pvs,
                         PropertyDescriptor[] pds, Object bean, String beanName)
     throws BeansException {
   System.out
       .println("InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法");
   return pvs;
 }
}
// bean配置
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
   xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
   xsi:schemaLocation="
     http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">

<bean id="beanPostProcessor" class="com.example.demo.MyBeanPostProcessor">
 </bean>

<bean id="instantiationAwareBeanPostProcessor" class="com.example.demo.MyInstantiationAwareBeanPostProcessor">
 </bean>

<bean id="beanFactoryPostProcessor" class="com.example.demo.MyBeanFactoryPostProcessor">
 </bean>

<bean id="book" class="com.example.demo.Book" init-method="myPostConstruct" destroy-method="myPreDestory">
   <!-- 注入bean 属性名称 -->
   <property name="bookName" value="thingking in java" />
 </bean>
</beans>
//调用
   ApplicationContext context = new ClassPathXmlApplicationContext("beanconfig.xml");
   Book book = (Book)context.getBean("book");
   System.out.println("Book name = " + book.getBookName());
   ((ClassPathXmlApplicationContext) context).destroy();

来源:https://www.cnblogs.com/frankltf/p/11449471.html

标签:spring,bean,生命,周期
0
投稿

猜你喜欢

  • 如何使用SpringSecurity保护程序安全

    2022-09-08 19:57:50
  • java emoji表情存储的解决方法

    2023-07-10 20:19:06
  • C#中out与ref的区别实例解析

    2022-01-27 13:29:09
  • opencv配置的完整步骤(win10+VS2015+OpenCV3.1.0)

    2023-06-28 14:55:19
  • 完美解决Spring Boot前端的Access-Control-Allow-Origin跨域问题

    2023-09-19 10:16:28
  • C#中DataTable 转换为 Json的方法汇总(三种方法)

    2021-12-12 16:41:00
  • Java实现图片拼接

    2023-02-28 23:01:27
  • java 算法之希尔排序详解及实现代码

    2022-07-12 23:09:45
  • C#递归实现回文判断算法

    2022-06-14 13:45:16
  • Spring Boot实现分布式系统中的服务发现和注册(最新推荐)

    2022-07-10 03:50:23
  • java控制台打印本月的日历

    2023-10-15 22:58:12
  • SpringCloud使用Zookeeper作为注册中心

    2023-11-21 20:28:20
  • Java Eclipse进行断点调试的方法

    2023-06-14 06:31:27
  • 解析MapStruct转换javaBean时出现的诡异事件

    2022-05-15 01:16:28
  • 使用controller传boolean形式值

    2023-11-28 23:05:33
  • java GUI编程之paint绘制操作示例

    2023-11-24 17:58:39
  • MybatisPlus使用@TableId主键id自增长无效的解决

    2023-01-30 15:59:41
  • 关于Mybatis插入对象时空值的处理

    2023-08-28 21:58:00
  • flutter轮子计划之进度条

    2023-06-21 07:59:39
  • java.net.SocketException: Connection reset 解决方法

    2023-06-17 01:28:43
  • asp之家 软件编程 m.aspxhome.com