Bean的2个作用域
Bean的作用域在<bean .../>
标签的scope
属性设定。如果scope="singleton"
则每次getBean("同一id")
得到的都是同一个对象;如果scope="prototype"
则每次getBean("同一id")
会创建新的对象。
Bean生命周期的2个重要方法
虽然Spring是低入侵的,也可以去实现一些它的接口来设定功能。如果一个Bean类实现了InitializingBean
接口,就可以覆写afterPropertiesSet()
方法来做初始化工作;如果一个Bean类实现了DisposableBean
接口,就可以覆写destroy()
方法来指定销毁工作。
为了让它真正的低抵入侵,完全可以不去实现这些接口和方法,而是去在Bean配置文件的<bean .../>
标签中配置。
使用init-method="初始化方法名"
属性指定无参的void类型初始化方法名;使用destroy-method="销毁方法名"
属性指定无参的void类型销毁方法名。
在Student类中添加
public void myInit() {
System.out.println("自定义的初始化方法被回调了");
}
public void myDestroy() {
System.out.println("自定义的销毁方法被回调了");
}
在对应的Bean中添加
init-method="myInit" destroy-method="myDestroy"
主函数中如使用
public static void main(String[] args) {
// 创建应用程序的上下文,加载Beans的配置文件,生成和初始化所有的对象
ClassPathXmlApplicationContext apct = new ClassPathXmlApplicationContext("./myXML/Beans.xml");
// 使用Bean的ID返回一个最终可以转换为实际对象的通用对象
Student sbLzh = (Student) apct.getBean("lzh");
// 用完关闭
apct.close();
// 输出看一下
System.out.println(sbLzh.getId());
System.out.println(sbLzh.getStuName());
}
运行结果
自定义的初始化方法被回调了
自定义的销毁方法被回调了
1856
刘知昊
说明并不是像析构函数那样在对象被回收时才做的回调,而是在关联的Bean工厂关闭时调用的。
对于ClassPathXmlApplicationContext
类,其实可以将它上转型成AbstractApplicationContext
类,其中的registerShutdownHook()
方法也能确保正确关闭。
如果所有的Bean都统一初始化或者销毁的方法的名称,完全可以在<beans .../>
标签里为这两个属性加上default-
前缀统一配置:
<?xml version="1.0" encoding="UTF-8"?>
<!-- 配置一些容器管理的Bean的对象 -->
<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-3.0.xsd"
default-init-method="myInit" default-destroy-method="myDestroy">
<!-- 给出这个对象的ID值(赋予一个唯一的名称),实现类 -->
<bean id="lzh" class="myBean.Student">
<!-- 要传递进去的对象的属性名,属性值 -->
<property name="id" value="1856" />
<property name="stuName" value="刘知昊" />
</bean>
</beans>
这样就不用对<bean .../>
一个一个配置了。
Bean的后置处理器
刚刚学了InitializingBean
接口和DisposableBean
接口分别可以让Bean类去覆写初始化和销毁时候所执行的操作。而`DisposableBean
接口提供的两个方法分别是在初始化方法之前和之后执行的操作:
bean标签的继承
通过为<bean .../>
标签指明parent
属性,可以达到让一个bean标签继承和覆写父标签的配置的功能,如:
<bean id="id1" class="实现类">
<property name="属性1" value="xxx"/>
<property name="属性2" value="xxx"/>
</bean>
<bean id="id2" class="实现类" parent="id1">
<property name="属性1" value="xxx"/>
<property name="属性3" value="xxx"/>
</bean>
则id2这个bean标签就继承了id1标签的属性2,还覆写了属性1,额外添加了属性3。具有继承关系的两个bean标签的实现类可以相同也可以不同,因为这和Java类本身的继承是无关的。
bean标签的抽象
正如抽象类的唯一作用是被继承一样,只要在bean标签中指定abstract="true"
,那么这个bean标签就被抽象为一个模板bean标签,用来给其它bean标签继承其属性。