文章目录
一、介绍
概念
Bean的生命周期是指一个Bean对象从创建到销毁的整个存在过程。
Bean生命周期组成:
1.实例化Bean(为Bean分配内存空间)
2.属性注入 (Bean注入和装配)
3.Bean的初始化
- 各种通知:如 BeanNameWare、BeanFactoryAware、ApplicationContextAware 的接口方法。
- 初始化前置方法
- 执行初始化方法 - 注解方式:@PostConstruct- xml 方式:init-method 方法
- 初始化后置方法
4.使用Bean
5.销毁Bean
注:
通过 @PostConstruct 注解方式初始化,需要在配置文件设置扫描路径;
通过 xml 方式初始化,需要在配置文件用标签中的 init-method 属性配置对应类的初始化方法名。
二、实例演示
spring-config.xml
<?xml version="1.0" encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:content="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><content:component-scanbase-package="com"></content:component-scan><beanid="beanLifeComponent"class="com.example.BeanLifeComponent"init-method="init"></bean></beans>
注:init-method 属性的值是 bean 对应的初始化方法的名称。如果该属性的值不匹配方法名,则在初始化 bean 时会抛出 NoSuchMethodException 异常。此处 ‘init’ 对应下面 xml 方式初始化方法名。
com.example.BeanLifeComponent.java
packagecom.example;importorg.springframework.beans.BeansException;importorg.springframework.beans.factory.BeanFactory;importorg.springframework.beans.factory.BeanFactoryAware;importorg.springframework.beans.factory.BeanNameAware;importorg.springframework.beans.factory.config.BeanPostProcessor;importorg.springframework.context.ApplicationContext;importorg.springframework.context.ApplicationContextAware;importjavax.annotation.PostConstruct;importjavax.annotation.PreDestroy;publicclassBeanLifeComponentimplementsBeanNameAware,BeanFactoryAware,ApplicationContextAware,BeanPostProcessor{/**
* 执行通知方法
* @param s
*/@OverridepublicvoidsetBeanName(String s){System.out.println("执行了BeanNameAware:BeanName = "+ s);}@OverridepublicvoidsetBeanFactory(BeanFactory beanFactory)throwsBeansException{System.out.println("执行了BeanFactoryAware:BeanFactory = "+ beanFactory);}@OverridepublicvoidsetApplicationContext(ApplicationContext applicationContext)throwsBeansException{System.out.println("执行了ApplicationContextAware:ApplicationContext = "+ applicationContext);}/**
* 执行初始化前置方法
* @param bean
* @param beanName
* @return
* @throws BeansException
*/@OverridepublicObjectpostProcessBeforeInitialization(Object bean,String beanName)throwsBeansException{System.out.println("执行初始化前置方法");return bean;}/**
* 执行初始化方法
*///xml 方式的初始化方法publicvoidinit(){System.out.println("XML 方式初始化");}//注解 方式初始化@PostConstructpublicvoidpostConstruct(){System.out.println("注解 方式初始化");}/**
* 执行初始化后置方法
* @param bean
* @param beanName
* @return
* @throws BeansException
*/@OverridepublicObjectpostProcessAfterInitialization(Object bean,String beanName)throwsBeansException{System.out.println("执行初始化后置方法");return bean;}/**
* 使用Bean
*/publicvoidsayHi(){System.out.println("使用Bean");}/**
* 销毁Bean
*/@PreDestroypublicvoidpreDestroy(){System.out.println("销毁Bean");}}
BeanLifeTest.java
importcom.example.BeanLifeComponent;importorg.springframework.context.support.ClassPathXmlApplicationContext;publicclassBeanLifeTest{publicstaticvoidmain(String[] args){//得到 Spring 容器,通过配置文件让Spring容器自动完成对象的实例化和属性注入。// 这里使用 ClassPathXmlApplicationContext 而不是 ApplicationContext,因为这个类没有destroy()或者close()方法。ClassPathXmlApplicationContext context =newClassPathXmlApplicationContext("spring-config.xml");//获取BeanBeanLifeComponent bean = context.getBean("beanLifeComponent",BeanLifeComponent.class);//使用Bean
bean.sayHi();//销毁Bean。下面两种方法等效//context.destroy();
context.close();}}
运行 BeanLifeTest.java 打印结果:
从打印结果我们可以发现:
1.使用注解方式初始化Bean比使用xml的优先级高。
2.为什么没有执行初始化前置和后置方法?
答:因为Bean的作用域默认是单例,Spring会自动调用初始化前置方法和后置方法,我们不能显示调用。要想显示调用,把Bean的作用域改为 prototype 即多例模式。可以在XML配置文件中使用元素的scope属性修改,也可在Bean定义中使用@Scope注解修改。
修改后
再次运行打印结果:
可以发现:
1.方法执行了两次。一个是在应用上下文启动时初始化的实例,另一个是在执行 getBean 方法时返回一个新的实例并初始化。
2.为什么没有执行销毁方法?
答:是因为Spring设计,多例模式的 Bean 由于会创建多个实例,因此容器不会自动跟踪和销毁这些实例,而是直接停掉了整个线程。
版权归原作者 愛夜 所有, 如有侵权,请联系我们删除。