bean的生命周期
其实前面聊servlet的时候也聊过生命周期,那么通过spring创建bean自然也有其生命周期,先说生命周期,然后再具体演示:
- 通过构造器创建bean实例,无论是有参无参都会先调用,毕竟不创建对象,后面的也就没有必须操作了。
- bean的初始化前通过后置处理器添加方法。
- 调用bean的初始化方法,这个配置初始化的方法。说白就是对属性进行赋值。
- bean的初始化后通过后置处理器添加方法。
- 为bean的属性设置时和对其它bean的引用,简单的说就是通过set方法。
- 可以得到bean的对象。
- 当容器关闭的时候,调用bean的销毁方法,但是这个需要配置销毁。
如果不明白实例化和初始化的区别,可以看另一篇文章:传送阵
首先创建一个java类Student:
package com.xzd.bean;
public class Student {
int age;
String name;
public Student( ) {
System.out.println("实例化");
}
public Student(int age, String name) {
this.age = age;
this.name = name;
}
public void setAge(int age) {
System.out.println("给学生设置年龄");
this.age = age;
}
public void setName(String name) {
System.out.println("给学生设置名字");
this.name = name;
}
public void initMethon(){
System.out.println("init--初始化方法");
}
public void destoryMethon(){
System.out.println("destory--销毁方法");
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
配置的xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="student" class="com.xzd.bean.Student" init-method="initMethon" destroy-method="destoryMethon">
</bean>
</beans>
在bean标签有两个属性一定要注意:
- init-method: 这个是配置spring中调用的初始化方法;
- destroy-method: 这个是配置spring调用的销毁方法,而这个销户的时候调用的方法。
现在开始调用方法:
public class testSpring {
public static void main(String[] args) {
// ApplicationContext applicationContext= new ClassPathXmlApplicationContext("spring_test.xml");
// 因为ApplicationContext 没有关闭关闭方法,所以无法调用destroy-method,所以需要用 ConfigurableApplicationContext
ConfigurableApplicationContext configurableApplicationContext=new ClassPathXmlApplicationContext("spring_test.xml");
Student student = configurableApplicationContext.getBean("student", Student.class);
student.setAge(10);
System.out.println(student);
configurableApplicationContext.close();
}
}
作用域对bean生命周期的影响
将上面的xml配置修改为一下两种:
-
单例模式:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="student" class="com.xzd.bean.Student" init-method="initMethon" destroy-method="destoryMethon" scope="singleton"> </bean> </beans>
-
多例模式:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="student" class="com.xzd.bean.Student" init-method="initMethon" destroy-method="destoryMethon" scope="prototype"> </bean> </beans>
这样依次调用:
public class testSpring {
public static void main(String[] args) {
// ApplicationContext applicationContext= new ClassPathXmlApplicationContext("spring_test.xml");
// 因为ApplicationContext 没有关闭关闭方法,所以无法调用destroy-method,所以需要用 ConfigurableApplicationContext
ConfigurableApplicationContext configurableApplicationContext=new ClassPathXmlApplicationContext("spring_test.xml");
Student student = configurableApplicationContext.getBean("student", Student.class);
student.setAge(10);
System.out.println(student);
configurableApplicationContext.close();
}
}
都是这个结果,好像没有什么不同。
然后只是加载配置文件代码如下:
public class testSpring {
public static void main(String[] args) {
// ApplicationContext applicationContext= new ClassPathXmlApplicationContext("spring_test.xml");
// 因为ApplicationContext 没有关闭关闭方法,所以无法调用destroy-method,所以需要用 ConfigurableApplicationContext
ConfigurableApplicationContext configurableApplicationContext=new ClassPathXmlApplicationContext("spring_test.xml");
//Student student = configurableApplicationContext.getBean("student", Student.class);
// student.setAge(10);
//System.out.println(student);
// configurableApplicationContext.close();
}
}
**单例模式 **下结果是:
**多例模式 **下结果是:
这样可以看出单例模式下加载配置文件的时候bean会直接创建好的,像是饿汉模式,毕竟创建对象后不会变,所以提前创建好,以供使用。
多例模式下bean加载配置文件的时候,有点像是懒汉模式了,就是什么时候使用,什么时候创建bean,毕竟每次创建都不同,所以没有必要提前创造好。
bean的后置处理器: 初始化前后添加方法
前面写spring中的的生命周期的时候,提到了一个初始化前后添加方法,而前面的例子中没有体现。因为这个用到了一个bean的后置处理器。
- 需要实现BeanPostProcessor接口。
- 需要通过配置配置给Spring容器中,这个需要注意一点,bean的后置处理器不是单独针对某一个bean生效,而是针对所有的spring容器中的bean生效。
现在开始演示:
这个需要单独创建一个实现BeanPostProcessor接口的接口类:
public class Myprocess implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("初始化前beanName="+ beanName+" bean="+bean);
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("初始化后beanName="+ beanName+" bean="+bean);
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
}
然后在配置文件中配置后置处理器:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="student" class="com.xzd.bean.Student" init-method="initMethon" destroy-method="destoryMethon" >
</bean>
<!-- 配置后置处理器 这个会对全部的bean有效果-->
<bean id="myprocess" class="com.xzd.bean.Myprocess"></bean>
</beans>
然后调用:
public class testSpring {
public static void main(String[] args) {
// ApplicationContext applicationContext= new ClassPathXmlApplicationContext("spring_test.xml");
// 因为ApplicationContext 没有关闭关闭方法,所以无法调用destroy-method,所以需要用 ConfigurableApplicationContext
ConfigurableApplicationContext configurableApplicationContext=new ClassPathXmlApplicationContext("spring_test.xml");
Student student = configurableApplicationContext.getBean("student", Student.class);
student.setAge(10);
System.out.println(student);
configurableApplicationContext.close();
}
}
然后作用域对其影响和带不带后置处理器效果几乎意义
- 如果是单例
- 如果是多例: