一. 概述
Spring中的org.springframeworks.bean和org.springframeworks.context两个包中的BeanFactory和AplicationContext两个类提供了管理Bean的配置机制,可实现Spring框架对Bean的管理。
二. JavaBean
JavaBean的作用是将Java创造的对象进行打包,并且使这些对象可由Servlet、Jsp页面、applet程序或其他应用来调用,且调用它们的用户不用关心其内部结构。
从根本来讲,Bean是一个黑盒结构,即不用关心其内部细节,只需要关心其功能与输入输出的程序结构。使用Bean构建程序时,我们可以忽略其内部结构,从而更加有效地把握程序的整体性能。
作为一个黑盒模型,Bean需要提供三个可供开发的接口面:Bean可供调用的方法、Bean中可读写的属性、Bean向外部发送或从外部接收的事件。
JavaBean有如下规范:
- JavaBean类必须是一个公共类,访问属性为public
- 必须有一个空的构造函数
- 不能有公共实例变量,类变量应该都为private
- 可访问属性应通过一组存取方法(getXxx、setXxx)来访问,例如对于属性Time应当有getTime方法和setTime方法
三. Bean的结构与性质
- name 和id
在一个Spring配置文档中,一个Bean有一个id,这个id对于管理Bean的BeanFactory和AplicationContext必须是唯一标识,是通过这两个类获取Bean实例时的唯一索引。
Spring中可以用name或id这两个属性来指定Bean的id,配置bean时必须在这两个属性中指定至少一个id。
用id属性指定一个Bean的id时,它在XML DTD中作为一个真正的XML元素的ID属性被标记,在其他元素指向它时XML解析器可以做一些额外的校验。但id属性需要遵守XML ID中对合法字符的严格限制。
需要使用非法字符或为Bean增加其他别名(超过一个id之外的其他id)时,可使用name属性指定一个或多个id,指定多个id时需要用逗号或分号间隔。
示例代码:
<bean id = “HelloWorld” name = “Hello” class = “com.gc.action.HelloWorld”>
2. class
Spring配置文档中class属性表示了Bean的实际路径
示例代码:
<bean id = “HelloWorld” class = “com.gc.action.HelloWorld”>
3.singleton
Spring中,Bean需要选择一种部署模式:singleton或non-singleton。默认模式为singleton。
如果一个Bean为singleton模式,则所有对这个Bean的请求都会返回一个唯一的共享实例
如果一个Bean为non-singleton模式,则每一次对这个Bean的请求都会返回一个全新的实例,类似于new操作
示例代码:
singleton模式
<bean id = “HelloWorld” class = “com.gc.action.HelloWorld”>
non-singleton模式
<bean id = “HelloWorld” class = “com.gc.action.HelloWorld” singleton = “false”>
4.Bean的属性
Spring中对于Bean的属性有两种注入方式:基于setter的依赖注入和基于构造函数的依赖注入。
基于setter的依赖注入:调用无参构造函数或无参静态工厂方法实例化配置文档中的Bean后,通过调用Bean上的setter方法实现。
基于构造函数的依赖注入:通过调用带有参数的构造方法实现,每个参数都代表一个对象或属性。
构造一个Bean HelloWorld
package.com.gc.action import java.util.Date public class HelloWorld{ //字符串 private String msg = null; //日期 private Date date = null; //构造函数 public HelloWorld(String msg){ this.msg = msg; } public void setMsg(String msg){ this.msg = msg; } public String getMsg(){ retrun this.msg; } public void setDate(Date date){ this.date = date; } public Date getDate(){ return this.date; } }
config.xml示例:
<?xml version = “1.0” encoding = “UTF-8”?> <!DOCTYPE beans PUBLIC “-//SPRING//DTD BEAN//EN” “http://springframework.org/dtd/spring-beans.dtd”> <beans> <bean id = “HelloWorld” class = “com.gc.action.HelloWorld”> <!—msg变量通过基于构造方法的依赖注入完成> <constructor-arg value = ”HelloWorld”> <!—date变量通过基于setter的依赖注入完成> <property name = “date” > <ref bean = “date”> </property> </bean> <bean id = “date” class = “java.util.Date/”> </beans>
测试程序TestHelloWorld
package com.gc.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; import com.gc.action.HelloWorld; import com.gc.impl.Hello; public class TestHelloWorld{ public static void main(String[] args){ //通过ApplicationContext来获取Spring的XML配置文件 ApplicationContext actx = new FileSystemXmlApplicationContext(“config.xml”); HelloWorld helloWorld = (HelloWorld)actx.getBean(“HelloWorld”); System.out.println(helloWorld.getDate()+””+helloWorld.getMsg()); } }
运行TestHelloWorld可输出结果
5. depends-on
depends-on属性可以在初始化当前Bean之前执行一个或多个Bean的初始化。
示例代码:
<bean id = “HelloWorld” class = “com.gc.action.HelloWorld” depends-on = “date”>
在初始化HelloWorld之前会强制初始化date
四. Bean的生命周期
- Bean的初始化
① 通过在配置文档中指定init-method属性完成
在HelloWorld.java中加入init()方法
package.com.gc.action import java.util.Date public class HelloWorld{ //字符串 private String msg = null; //日期 private Date date = null; public void init(){ this.msg = “HelloWorld”; this.date = new Date(); } public void setMsg(String msg){ this.msg = msg; } public String getMsg(){ retrun this.msg; } public void setDate(Date date){ this.date = date; } public Date getDate(){ return this.date; } }
在config.xml中指定init-method
<?xml version = “1.0” encoding = “UTF-8”?> <!DOCTYPE beans PUBLIC “-//SPRING//DTD BEAN//EN” “http://springframework.org/dtd/spring-beans.dtd”> <beans> <!—指定init-method完成Bean的初始化> <bean id = “HelloWorld” class = “com.gc.action.HelloWorld” init-method = “init”> </bean> </beans>
② 实现org.springframework.beans.factory.InitializingBean接口
需要在HelloWorld.java中实现InitializingBean接口,并增加afterPropertiesSet()方法来完成初始化
package.com.gc.action import java.util.Date import org.springframework.beans.factory.InitializingBean public class HelloWorld implements InitializingBean{ //字符串 private String msg = null; //日期 private Date date = null; //初始化 public void afterPropertiesSet(){ this.msg = “HelloWorld”; this.date = new Date(); } public void setMsg(String msg){ this.msg = msg; } public String getMsg(){ retrun this.msg; } public void setDate(Date date){ this.date = date; } public Date getDate(){ return this.date; } }
修改config.xml
<?xml version = “1.0” encoding = “UTF-8”?> <!DOCTYPE beans PUBLIC “-//SPRING//DTD BEAN//EN” “http://springframework.org/dtd/spring-beans.dtd”> <beans> <bean id = “HelloWorld” class = “com.gc.action.HelloWorld” > </bean> </beans>
2. Bean的使用
① 使用Bean Wrapper
代码示例:
HelloWorld helloWorld = new HelloWorld(); BeanWrapper bw = new BeanWrapperImpl(helloWorld); bw.setPropertyValue(“msg”, “HelloWorld”); System.out.println(bw.getPropertyValue(“msg”));
② 使用BeanFactory
代码示例:
InputStream is = new FileInputStream(“config.xml”); XmlBeanFactory factory = new XmlBeanFactory(is); HelloWorld helloWorld = (HelloWorld)factory.getBean(“HelloWorld”); System.out.println(helloWorld.getMsg());
③ 使用ApplicationContext
代码示例:
ApplicationContext actx = new FileSystemXmlApplicationContext(“config.xml”); HelloWorld helloWorld = (HelloWorld)actx.getBean()
3. Bean的销毁
① 通过在配置文档中指定destroy-method属性完成
在HelloWorld中添加用于销毁的cleanUp()方法
package.com.gc.action import java.util.Date public class HelloWorld { //字符串 private String msg = null; //日期 private Date date = null; //初始化 public void init(){ this.msg = “HelloWorld”; this.date = new Date(); } public void cleanup(){ this.msg = “”; this.date = null; System.out.println(“cleaned up”); } public void setMsg(String msg){ this.msg = msg; } public String getMsg(){ retrun this.msg; } public void setDate(Date date){ this.date = date; } public Date getDate(){ return this.date; } }
配置文件
<?xml version = “1.0” encoding = “UTF-8”?> <!DOCTYPE beans PUBLIC “-//SPRING//DTD BEAN//EN” “http://springframework.org/dtd/spring-beans.dtd”> <beans> <!—指定init-method完成Bean的初始化,指定destroy-method完成Bean的销毁> <bean id = “HelloWorld” class = “com.gc.action.HelloWorld” init-method = “init” destroy-method = “cleanUp”> </bean> </beans>
② 实现org.springframework.beans.factory.DisposableBean接口,在HelloWorld中添加一个destroy()方法完成销毁
package.com.gc.action import java.util.Date import org.springframework.beans.factory.InitializingBean import org.springframework.beans.factory.DisposableBean public class HelloWorld implements DisposableBean{ //字符串 private String msg = null; //日期 private Date date = null; //初始化 public void afterPropertiesSet(){ this.msg = “HelloWorld”; this.date = new Date(); } public void destroy(){ this.msg = “”; this.date = null; System.out.println(“Bean destroyed”); } public void setMsg(String msg){ this.msg = msg; } public String getMsg(){ retrun this.msg; } public void setDate(Date date){ this.date = date; } public Date getDate(){ return this.date; } }
配置文档:
<?xml version = “1.0” encoding = “UTF-8”?> <!DOCTYPE beans PUBLIC “-//SPRING//DTD BEAN//EN” “http://springframework.org/dtd/spring-beans.dtd”> <beans> <bean id = “HelloWorld” class = “com.gc.action.HelloWorld” > </bean> </beans>