Bean的生命周期指的是我们的一个对象从创建到销毁的全部过程。
对于普通的 Java 对象,当 new 的时候创建对象,然后该对象就能够使用了。一旦该对象不再被使用,则由 Java 自动进行垃圾回收。
而 Spring 中的对象是 bean,bean 和普通的 Java 对象没啥大的区别,只不过 Spring 不再自己去 new 对象了,而是由 IoC 容器去帮助我们实例化对象并且管理它,我们需要哪个对象,去问 IoC 容器要即可。IoC 其实就是解决对象之间的耦合问题,Spring Bean 的生命周期完全由容器控制。
————————————————
原文链接:https://blog.csdn.net/riemann_/article/details/118500805
Spring容器只对单例的bean全过程管理,对于多类的bean只会管理到客户端程序拿到bean
- 首先是五步,五步有以下五步
- 第一步 实例化(无参构造)
- 第二步 Bean属性赋值(bean.xml中配置)
- 第三步 初始化Bean(调用bean的init()方法,需要自己写一下,自己配置)
- 第四步 使用Bean
- 第五步 销毁Bean(调用bean的destory方法,需要自己写一下,自己配置){
- 想要销毁Bean,必须手动关闭spring容器,才能销毁bean
- }
我们来个简单的例子记录一下
首先来个简单的对象
public class Role {
private String name;
public Role(){
System.out.println("第一步:实例化Bean,执行了无参的构造方法");
}
public void print(){
System.out.println(this.name);
}
}
一个set,一个打印方法
然后我们配置bean
<bean id="RoelBean" class="com.chenchen.dao.Role" >
<property name="name" value="绘梨衣"></property>
</bean>
set注入,此时我们给出测试程序
会输出 绘梨衣
这是原本的一个把对象交给Spring容器的bean的过程
那么问题来了??
我们想在set注入值后要实例化的值怎么办??我们创建的bean不用了怎么办,要知道普通的java对象在不使用的时候会自动的被gc回收垃圾,而bean对象需要我们手动的destory,这样的话我们给出 initBean 和 destoryBean的方法,可以在initBean中修改和赋值
给出完善的类
public class Role {
private String name;
public Role(){
System.out.println("第一步:实例化Bean,执行了无参的构造方法");
}
public void setName(String name) {
System.out.println("第二步:给Bean赋值,也就是set注入");
this.name = name;
}
// 初始化Bean,通过name赋值测试是否可以覆盖掉 绘梨衣
public void initBean(){
this.name="路明非";
System.out.println("第三步:初始化Bean");
}
// 销毁Bean
public void destoryBean(){
System.out.println("第五步:销毁Bean");
}
public void print(){
System.out.println(this.name);
}
}
我们给出bean.xml
<bean id="RoelBean" class="com.chenchen.dao.Role" init-method="initBean" destroy-method="destoryBean" >
<property name="name" value="绘梨衣"></property>
</bean>
init-method="initBean" destroy-method="destoryBean" 是要写出我们手写额init 和 destory 而且这两个方法会被容器自动调用
然后我们给出测试方法
请注意: 只有关闭Spring容器后,才能执行 deatoryBean方法,而我们需要手动关闭spring容器,并且需要用ClassPathXmlApplicationContext才能关闭spring容器
public void RoleTest(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
Role role = applicationContext.getBean("RoelBean",Role.class);
role.print();
ClassPathXmlApplicationContext context = (ClassPathXmlApplicationContext) applicationContext;
context.close();
}
}
此时可以打印结果如下:
spring容器会自动调用init 和destory方法,不需要我们手动调用,再次强调
(浅谈理解:个人猜测applicationContext是一个配置文件对应一个容器的开关,关闭它那么就关闭了该配置文件对应的容器。init destory是为了丰富我们对应对象的操作,但是我不知道这么和上饿面的对象工厂联系起来)
然后就是七步生命周期,在五步上增加了两步
在此我们需要新建一个类并且实现
BeanPostProcessor
这个接口的 before 和 after两个方法 ,也叫Bean后处理器
我们可以在 <-------------------------->添加代码
- 第一步 实例化(无参构造)
- 第二步 Bean属性赋值(bean.xml中配置)
- <------------before---------------->
- 第三步 初始化Bean(调用bean的init()方法,需要自己写一下,自己配置)
- <------------------after------------->
- 第四步 使用Bean
- 第五步 销毁Bean
给出增加的代码
public class RoleBeanPostProcesser implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
}
给出bean.xml配置,其实就是将新加的类添加到bean.xml中
<bean id="RoelBean" class="com.chenchen.dao.Role" init-method="initBean" destroy-method="destoryBean" >
<property name="name" value="绘梨衣"></property>
</bean>
<bean id="RoleBeanPost" class="com.chenchen.dao.RoleBeanPostProcesser"/>
运行如下:
第一步:实例化Bean,执行了无参的构造方法
第二步:给Bean赋值,也就是set注入
新加的一步执行Bean前处理器
第三步:初始化Bean
新加的一步执行Bean后处理器
路明非
第五步:销毁Bean
Test代码不用改变,无论是工厂类的创建方式还是对bean生命周期的操纵都不需要改变测试代码
将自己new的生命周期纳入spring容器管理,需要使用
DefaultListableBeanFactory
给出新new的
public void test(){
Role role = new Role();
role.setName("绘梨衣");
role.print();
}
运行如下
第一步:实例化Bean,执行了无参的构造方法
第二步:给Bean赋值,也就是set注入
绘梨衣
我们手动创建 set值 ,那么如何交给spring管理呢
需要完成DefaultListableBeanFactory 的建立,注册
@Test
public void test(){
Role role = new Role();
System.out.println(role);
// 创建工厂
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
// 将我们新建的bean注入spring容器
factory.registerSingleton("RoleBean",role);
// 获得对象
Object roleBean = factory.getBean("RoleBean");
System.out.println(roleBean);
}
然后我们输出
com.chenchen.dao.Role@d041cf
com.chenchen.dao.Role@d041cf
可以看到两个是同一个
请注意 :factory.registerSingleton("RoleBean",role)
this要写自己new的名字
以上就是本次内容