[b][size=large] 第16章 核心机制-----IOC[/size][/b]
[b]本章导读语[/b]
Spring框架所提供的众多功能之所以能成为一个整体正是建立在IoC的基础之上,IoC是Spring中极其重要的一部分,可谓是Spring的灵魂。
本章将讲述IoC的知识,包括IoC的相关概念(例如实现的基本原理、IoC容器的概念等),另外还将讲述实例化容器和bean的几种方式,以及Spring中注入的几种方式。另外,Spring一般采用XML格式来配置,因此还讲述了Spring的基本配置,并重点讲述了bean属性及构造参数的配置。
[size=large][b]一. 解说IoC的相关概念[/b][/size]
[b]1. 建立工程(建立一个名为springioc的web工程)[/b]
[b]2. 控制反转的基本原理(IoC指的就是由容器控制程序之间的关系,而非传统实现中,由程序代码直接控制。即组件之间的依赖关系由容器在运行期决定,下面以实例的形式演示IoC的原理)[/b]
(1) 编写影片类:Movie.java
(2)编写影片查找器接口类:MovieFinder.java
(3)编写影片查找器SampleMovieFinder.java
(4)编写影片查找器工厂类:sampleMovieFinder.java
Spring中的IoC所起的作用就相当于MovieFinderFactory类,它负责给需要某接口的实现类的某个类注入实现类。
[size=large][b]二. XML格式配置元数据[/b][/size]
[b]1. 基本结构[/b]
[b]2.<beans>元素的配置[/b]
<beans>为配置文件的根元素,它可包含0到多个<bean>元素。它有如下属性:
(1) default-autowire:该属性用于指定默认的bean自动装配模式。
(2) default-dependency-check:该属性用于指定默认的依赖检查模式。
none:不进行依赖检查。没有指定值的bean属性仅仅是没有设值。
Simple:对于基本类型和集合(除了合作者外,比如其他的bean,所有东西)进行依赖检查。
Object:对合作者进行信赖检查。
All:对合作者,基本类型和集合都进行依赖检查。
(3)Default-lazy-init:该属性用于指定是否默认延迟加载。值为true表示延迟加载,为false表示非延迟加载
3.<bean>元素的基本配置
<bean>元素为<beans>元素的子元素,它用于指明Spring容器一个类以及指明它是如何配置的。它具有如下属性:
class:该属性用于指定类的全路径,例如amigo.spring.chapter16.SMSSender.
id:class属性对应的类在BeanFactory中的唯一标识,代码中可通过该名称在BeanFactory获取类实例。
name:同上,如果给bean增加别名,可以通过name属性指定一个或多个id
scope:用于指定bean的作用域。Spring支持5种作用域
abstract:设定ApplicationContext是否对bean进行预先的初始化。
parent:定义一个模板。
autowire:bean自动装配模式。
dependency-check:依赖检查模式,同<beans>元素的default-dependency-check属性。
lazy-init:延迟加载。
init-method:该属性用于指定初始化方法,一般用于一些资 源的初始化工作。
destroy-method:该属性用于指定销毁方法。
factory-bean:该属性用于指定通过实例工厂方法创建bean,class属性必须为空,factory-bean属性必须指定一个bean的名字,这个bean一定要在当前的bean工厂或者父bean工厂中,并包含工厂方法。
factory-method:该属性用于设定工厂类的工厂方法。
depends-on:该属性用于指定Bean依赖关系。一般情况下无需设定。通过depends-on指定其依赖关系可保证在此Bean加载之前,首先对depends-on所指定的资源进行加载。
[b]4.<property>元素的基本配置[/b]
<property>属性为<bean>元素的子元素,它用于设轩置一个属性。
name:该属性用于指定属性的名称。
value:用于指定bean的属性值。
ref:指定了属性对BeanFactory中其他Bean的引用关系。
[size=large][b]三. 实例化容器的几种方法[/b][/size]
[b]1. 创建包amigo.sqring.ioc.container[/b]
[b]2. 编写辅助测试Bean:HelloBean.java[/b]
[b]3. 编写Spring配置文件:container.xml(该文件定义了一个bean:helloBean,指定的类为amigo.spring.ioc.container.HelloBean)[/b]
[b]4. 获取Spring配置文件的三种方法(创建测试类Test.java)[/b]
[b]5. 容器的使用,容器接口类BeanFactory包括如下方法:[/b]
(1)containsBean(String):如果BeanFactory包含给定名称的bean定义(或bean实例),则返回true.
(2) getBean(String):返回以给定名字注册的bean实例。
(3)getBean(String ,Class):返回以给定名称注册的bean实例,并转换为给定class类型的实
(4)getType(String name):返回给定名称的bean的class.
(5)isSingleton(String):判断给定名称的bean定义(或bean实例)是否为singleton模式。
(6)getAliases(String):返回给定bean名称的所有别名的数组。
为了讲述其使用,在amigo.spring.ioc.container中创建ContainerUser.java类,该类的代码如下:
[size=large][b]四. 实例化bean的3种方式[/b][/size]
就Spring IoC容器而言,bean定义基本上描述了创建一个或多个实际bean对象的内容,当需要的时候,容器会从bean定义列表中取得一个指定的bean定义,并根据bean定义里面的配置元数使用反射机制来创建一个实际的对象。
[b]1. 创建包amigo.spring.ioc.bean[/b]
[b]2. 编写用户对象类:UserBean.java[/b]
[b]3.编写UserBean的工厂类:UserBeanFactory.java[/b]
[b]4.编写测试类:Test.java[/b]
[b]5.用构造器实例化(bean1.xml)[/b]
[b]6. 使用静态工厂方法实例化(bean2.xml)[/b]
[b]7. 使用实例工厂方法实例化(bean3.xml)[/b]
最后运行结果为:
使用构造器实例化,username=null,password=null
使用静态工厂方法实例化,username=amigo1,password=123
使用实例工厂方法实例化,username=amigo2,password=123456
[size=large][b]五. 注入方式---构造子注入[/b][/size]
[b]1. 建立包目录[/b]
[b]2. 编写短信类SMSSender.java(SMSSender1.java类用于发送短信,所需要的参数采用构造函数的方式注入,本例只是演示Spring构造函数注入的方式,所以发送短信的方法并没有给出实现,该类的代码如下所示:)[/b]
[b]3. 编写Spring配置文件,具体内容如下:[/b]
[b]4. 编写测试类TestSMSSender1.java[/b]
最后结果打印出了srcTermID的值为:13555555555
[size=large][b]六. 注入方式 ---setter方法注入[/b][/size]
[b]1. 编写短信类SMSSender2.java(此类与SMSSender1.java略有不同,它去掉了构造函数)[/b]
[b]2.修改配置文件applicationContext.xml
添加如下bean:[/b]
[b]3.编写测试类:[/b]
[size=large][b]七.注入方式---接口注入[/b][/size]
[b] 1.编写接口类UserBean.java[/b]
[b]2.编写实现类UserBeanImpl.java[/b]
[b]3.编写接口注入类InterfaceInject.java[/b]
[b]4.编写Spring配置文件(在原有的配置文件上加上如下的bean)[/b]
[b]5.编写测试类[/b]
[b]
[size=large]八. Bean属性及构造器参数[/size][/b]
下面来看一个直接量使用的举例,在DbConnection类中,driverClassName(驱动器类名)、url(数据库连接路径)、username(数据库用户名)和password(数据库密码)属性都需要在Spring中进行配置。
[b]1. 配置直接量[/b]
(1) 编写测试类:DataSource.java
(2) 编写配置文件:Beanproperties.xml
[b]2. 引用其他的bean[/b]
(1) 编写测试类:User.java
(2) 编写依赖类:Dept.java
(3)修改配置文件:beanproperties.
[b]3. 内部bean(内部bean是指在一个bean的<property/>或<constructor-arg/>元素中使用<bean/>元素定义的bean)[/b]
(1)编写测试类:OuterBean.java
(2)编写内部bean类:InnerBean.java
(3)修改配置文件:beanproperties.xml
[b]4. 在配置文件中配置集合[/b]
(1) 编写测试类:CollectionTest.java
(3) 修改配置文件:beanproperties.xml
[b]本章导读语[/b]
Spring框架所提供的众多功能之所以能成为一个整体正是建立在IoC的基础之上,IoC是Spring中极其重要的一部分,可谓是Spring的灵魂。
本章将讲述IoC的知识,包括IoC的相关概念(例如实现的基本原理、IoC容器的概念等),另外还将讲述实例化容器和bean的几种方式,以及Spring中注入的几种方式。另外,Spring一般采用XML格式来配置,因此还讲述了Spring的基本配置,并重点讲述了bean属性及构造参数的配置。
[size=large][b]一. 解说IoC的相关概念[/b][/size]
[b]1. 建立工程(建立一个名为springioc的web工程)[/b]
[b]2. 控制反转的基本原理(IoC指的就是由容器控制程序之间的关系,而非传统实现中,由程序代码直接控制。即组件之间的依赖关系由容器在运行期决定,下面以实例的形式演示IoC的原理)[/b]
(1) 编写影片类:Movie.java
package amigo.spring.ioc.conception;
/**
* 影片类
* */
public class Movie {
/**影片ID.*/
private long id;
/**影片名称*/
private String name;
/**导演*/
private String director;
/**男演员*/
private String actor;
/**女演员*/
private String actree;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDirector() {
return director;
}
public void setDirector(String director) {
this.director = director;
}
public String getActor() {
return actor;
}
public void setActor(String actor) {
this.actor = actor;
}
public String getActree() {
return actree;
}
public void setActree(String actree) {
this.actree = actree;
}
}
(2)编写影片查找器接口类:MovieFinder.java
package amigo.spring.ioc.conception;
import java.util.List;
public interface MovieFinder {
List findAll();
}
(3)编写影片查找器SampleMovieFinder.java
package amigo.spring.ioc.conception;
import java.util.ArrayList;
import java.util.List;
/**查找器方法实现类*/
public class SampleMovieFinder implements MovieFinder {
public List findAll(){
List moveList = new ArrayList();
Movie movie1 = new Movie();
movie1.setId(1);
movie1.setName("花样年华");
movie1.setActree("张曼玉");
movie1.setActor("梁朝伟");
movie1.setDirector("王家卫");
moveList.add(movie1);
Movie movie2 = new Movie();
movie2.setId(2);
movie2.setName("茉莉 花");
movie2.setActree("章子怡");
moveList.add(movie2);
Movie movie3 = new Movie();
movie3.setId(3);
movie3.setName("玉观音");
movie3.setActree("孙俪");
movie3.setActor("佟大为");
moveList.add(movie3);
Movie movie4 = new Movie();
movie4.setId(4);
movie4.setName("2046");
movie4.setActree("张曼玉");
moveList.add(movie4);
return moveList;
}
}
(4)编写影片查找器工厂类:sampleMovieFinder.java
package amigo.spring.ioc.conception;
/**影片查找器的工作类*/
public class MovieFinderFactory {
public static MovieFinder getFinder(String finderName){
MovieFinder finder= null;
if("sampleFinder".equals(finderName)){
finder = new SampleMovieFinder();
}else{
}
return finder;
}
}
(5)编写测试类:MovieLister.java
package amigo.spring.ioc.conception;
import java.util.Iterator;
import java.util.List;
class MovieLister {
private MovieFinder finder ;
public MovieLister(){
finder = MovieFinderFactory.getFinder("sampleFinder");
}
public Movie[] moviesActressBy(String arg){
List allMovies = finder.findAll();
for(Iterator it=allMovies.iterator();it.hasNext();){
Movie movie = (Movie)it.next();
if(!movie.getActree().equals(arg)){
it.remove();
}
}
return (Movie[]) allMovies.toArray(new Movie[allMovies.size()]);
}
public static void main(String[] args){
MovieLister lister = new MovieLister();
Movie[] movies = lister.moviesActressBy("张曼玉");
System.out.println("有"+movies.length+"部电影");
for(int i=0;i<movies.length;i++){
Movie movie = movies[i];
System.out.println("影片id="+movie.getId()+",影片名称="+movie.getName());
}
}
}
Spring中的IoC所起的作用就相当于MovieFinderFactory类,它负责给需要某接口的实现类的某个类注入实现类。
[size=large][b]二. XML格式配置元数据[/b][/size]
[b]1. 基本结构[/b]
<?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-2.0.xsd">
<bean id=" " class="" >
……….
</bean>
<bean id=" " class="" >
……….
</bean>
</beans>
[b]2.<beans>元素的配置[/b]
<beans>为配置文件的根元素,它可包含0到多个<bean>元素。它有如下属性:
(1) default-autowire:该属性用于指定默认的bean自动装配模式。
(2) default-dependency-check:该属性用于指定默认的依赖检查模式。
none:不进行依赖检查。没有指定值的bean属性仅仅是没有设值。
Simple:对于基本类型和集合(除了合作者外,比如其他的bean,所有东西)进行依赖检查。
Object:对合作者进行信赖检查。
All:对合作者,基本类型和集合都进行依赖检查。
(3)Default-lazy-init:该属性用于指定是否默认延迟加载。值为true表示延迟加载,为false表示非延迟加载
3.<bean>元素的基本配置
<bean>元素为<beans>元素的子元素,它用于指明Spring容器一个类以及指明它是如何配置的。它具有如下属性:
class:该属性用于指定类的全路径,例如amigo.spring.chapter16.SMSSender.
id:class属性对应的类在BeanFactory中的唯一标识,代码中可通过该名称在BeanFactory获取类实例。
name:同上,如果给bean增加别名,可以通过name属性指定一个或多个id
scope:用于指定bean的作用域。Spring支持5种作用域
abstract:设定ApplicationContext是否对bean进行预先的初始化。
parent:定义一个模板。
autowire:bean自动装配模式。
dependency-check:依赖检查模式,同<beans>元素的default-dependency-check属性。
lazy-init:延迟加载。
init-method:该属性用于指定初始化方法,一般用于一些资 源的初始化工作。
destroy-method:该属性用于指定销毁方法。
factory-bean:该属性用于指定通过实例工厂方法创建bean,class属性必须为空,factory-bean属性必须指定一个bean的名字,这个bean一定要在当前的bean工厂或者父bean工厂中,并包含工厂方法。
factory-method:该属性用于设定工厂类的工厂方法。
depends-on:该属性用于指定Bean依赖关系。一般情况下无需设定。通过depends-on指定其依赖关系可保证在此Bean加载之前,首先对depends-on所指定的资源进行加载。
[b]4.<property>元素的基本配置[/b]
<property>属性为<bean>元素的子元素,它用于设轩置一个属性。
name:该属性用于指定属性的名称。
value:用于指定bean的属性值。
ref:指定了属性对BeanFactory中其他Bean的引用关系。
[size=large][b]三. 实例化容器的几种方法[/b][/size]
[b]1. 创建包amigo.sqring.ioc.container[/b]
[b]2. 编写辅助测试Bean:HelloBean.java[/b]
package amigo.spring.ioc.container;
/**
* 实例化容器实例辅助类,用于输出Hello信息.
* */
public class HelloBean {
public void sayHelloWorld(){
System.out.println("hello,amigo");
}
}
[b]3. 编写Spring配置文件:container.xml(该文件定义了一个bean:helloBean,指定的类为amigo.spring.ioc.container.HelloBean)[/b]
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="helloBean" class="amigo.spring.ioc.container.HelloBean"></bean>
</beans>
[b]4. 获取Spring配置文件的三种方法(创建测试类Test.java)[/b]
package amigo.spring.ioc.container;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
/**
* 实例化容器测试类
* */
public class Test {
public static void main(String[] args){
//方式一:在CLASSPATH路径下获取XMLBeanFactory实例
ClassPathResource res = new ClassPathResource("container.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);
HelloBean hellobean = (HelloBean)factory.getBean("helloBean");
hellobean.sayHelloWorld();
//方式二:指定绝对路径建ApplicatinContext实例
FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext("D:\\My_Struts_Cvs8\\springioc\\src\\container.xml");
BeanFactory factory2 = (BeanFactory) context;
HelloBean hellobean2 = (HelloBean)factory2.getBean("helloBean");
hellobean2.sayHelloWorld();
//方式三:通过ClassPathXmlApplicationContext创建BeanFactory实例
ClassPathXmlApplicationContext context3 = new ClassPathXmlApplicationContext("container.xml");
BeanFactory factory3 = (BeanFactory) context3;
HelloBean hellobean3 = (HelloBean)factory3.getBean("helloBean");
hellobean3.sayHelloWorld();
}
}
[b]5. 容器的使用,容器接口类BeanFactory包括如下方法:[/b]
(1)containsBean(String):如果BeanFactory包含给定名称的bean定义(或bean实例),则返回true.
(2) getBean(String):返回以给定名字注册的bean实例。
(3)getBean(String ,Class):返回以给定名称注册的bean实例,并转换为给定class类型的实
(4)getType(String name):返回给定名称的bean的class.
(5)isSingleton(String):判断给定名称的bean定义(或bean实例)是否为singleton模式。
(6)getAliases(String):返回给定bean名称的所有别名的数组。
为了讲述其使用,在amigo.spring.ioc.container中创建ContainerUser.java类,该类的代码如下:
package amigo.spring.ioc.container;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
/**
* 展示容器对象BeanFactory的使用
* */
public class ContainerUser {
public static void main(String[] args){
ClassPathResource res = new ClassPathResource("container.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);
boolean containFlag = factory.containsBean("helloBean");
System.out.println("是否包含名为helloBean的bean:"+containFlag);
if(containFlag){
HelloBean hellobean =(HelloBean)factory.getBean("helloBean");
hellobean.sayHelloWorld();
System.out.println("成功通过getBean(String)获得Bean实例");
HelloBean hellobean2 =(HelloBean)factory.getBean("helloBean",HelloBean.class);
hellobean2.sayHelloWorld();
System.out.println("成功通过getBean(String,Class)获得Bean实例");
boolean isSingleton = factory.isSingleton("helloBean");
System.out.println("helloBean是否为Singleton:"+isSingleton);
Class type = factory.getType("helloBean");
System.out.println("helloBean的类的类型为:"+type.getName());
String[] aliases=factory.getAliases("helloBean");
System.out.println("helloBean的类的别名个数为:"+aliases.length);
}
}
}
[size=large][b]四. 实例化bean的3种方式[/b][/size]
就Spring IoC容器而言,bean定义基本上描述了创建一个或多个实际bean对象的内容,当需要的时候,容器会从bean定义列表中取得一个指定的bean定义,并根据bean定义里面的配置元数使用反射机制来创建一个实际的对象。
[b]1. 创建包amigo.spring.ioc.bean[/b]
[b]2. 编写用户对象类:UserBean.java[/b]
package amigo.spring.ioc.bean;
/**
* 用户对象
* */
public class UserBean {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
/**
*创建UserBean对象
*@retrun 返回UserBean对象,
*设置其username为:amigo1,密码为:123
**/
public static UserBean createUserBean(){
UserBean user=new UserBean();
user.setUsername("amigo1");
user.setPassword("123");
return user;
}
}
[b]3.编写UserBean的工厂类:UserBeanFactory.java[/b]
package amigo.spring.ioc.bean;
/**
* UserBean的工厂类.
**/
public class UserBeanFactory {
/**
* 创建UserBean对象。
* @return返回UserBean对象,
* 设置其username为:amigo2,密码为:123456 注:需要注意的是,使用实例化工厂方法时,该方法不能声明static.
* */
public UserBean createUserBean(){
UserBean user = new UserBean();
user.setUsername("amigo2");
user.setPassword("123456");
return user;
}
}
[b]4.编写测试类:Test.java[/b]
package amigo.spring.ioc.bean;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
/**
* bean实例化测试类
* */
public class Test {
public static void main(String[] args){
//使用构造器实例化
ClassPathResource res1 = new ClassPathResource("bean1.xml");
XmlBeanFactory factory1 = new XmlBeanFactory(res1);
UserBean userBean1 = (UserBean)factory1.getBean("userBean");
System.out.println("使用构造器实例化,username="+userBean1.getUsername()+",password="+userBean1.getPassword());
//使用静态工厂方法实例化
ClassPathResource res2 = new ClassPathResource("bean2.xml");
XmlBeanFactory factory2 = new XmlBeanFactory(res2);
UserBean userBean2 = (UserBean)factory2.getBean("userBean");
System.out.println("使用静态工厂方法实例化,username="+userBean2.getUsername()+",password="+userBean2.getPassword());
//使用实例工厂方法实例化
ClassPathResource res3 = new ClassPathResource("bean3.xml");
XmlBeanFactory factory3 = new XmlBeanFactory(res3);
UserBean userBean3 = (UserBean)factory3.getBean("userBean");
System.out.println("使用实例工厂方法实例化,username="+userBean3.getUsername()+",password="+userBean3.getPassword());
}
}
[b]5.用构造器实例化(bean1.xml)[/b]
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="userBean" class="amigo.spring.ioc.bean.UserBean"></bean>
</beans>
[b]6. 使用静态工厂方法实例化(bean2.xml)[/b]
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="userBean" class="amigo.spring.ioc.bean.UserBean" factory-method="createUserBean"/>
</beans>
[b]7. 使用实例工厂方法实例化(bean3.xml)[/b]
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="userBeanFactory" class="amigo.spring.ioc.bean.UserBeanFactory"/>
<bean id="userBean" factory-bean="userBeanFactory" factory-method="createUserBean"/>
</beans>
最后运行结果为:
使用构造器实例化,username=null,password=null
使用静态工厂方法实例化,username=amigo1,password=123
使用实例工厂方法实例化,username=amigo2,password=123456
[size=large][b]五. 注入方式---构造子注入[/b][/size]
[b]1. 建立包目录[/b]
[b]2. 编写短信类SMSSender.java(SMSSender1.java类用于发送短信,所需要的参数采用构造函数的方式注入,本例只是演示Spring构造函数注入的方式,所以发送短信的方法并没有给出实现,该类的代码如下所示:)[/b]
package amigo.spring.chapter16;
/**
* 短信发送
* */
public class SMSSender1 {
public SMSSender1(
int msgType,
int needReport,
int msgLevel,
String serviceID,
int msgFormat,
String feeType,
int feeUserType,
String feeCode,
String validTime,
String atTime,
String srcTermID
){
this.msgType=msgType;
this.needReport=needReport;
this.msgLevel=msgLevel;
this.serviceID=serviceID;
this.msgFormat=msgFormat;
this.feeType=feeType;
this.feeUserType=feeUserType;
this.feeCode=feeCode;
this.validTime=validTime;
this.atTime=atTime;
this.srcTermID=srcTermID;
}
/**0消息类型*/
int msgType;
/**1是否需要状态报告*/
int needReport;
/**1消息发送优先级别*/
int msgLevel;
/**11111 业务代码*/
String serviceID;
/**15消息格式*/
int msgFormat;
/**01计费类型*/
String feeType;
/**00用户类型*/
int feeUserType;
/**123456计费代码*/
String feeCode;
/**有效期*/
String validTime;
/**定时发送时间*/
String atTime;
/**11111源用户号码*/
String srcTermID;
public int getMsgType() {
return msgType;
}
public void setMsgType(int msgType) {
this.msgType = msgType;
}
public int getNeedReport() {
return needReport;
}
public void setNeedReport(int needReport) {
this.needReport = needReport;
}
public int getMsgLevel() {
return msgLevel;
}
public void setMsgLevel(int msgLevel) {
this.msgLevel = msgLevel;
}
public String getServiceID() {
return serviceID;
}
public void setServiceID(String serviceID) {
this.serviceID = serviceID;
}
public int getMsgFormat() {
return msgFormat;
}
public void setMsgFormat(int msgFormat) {
this.msgFormat = msgFormat;
}
public String getFeeType() {
return feeType;
}
public void setFeeType(String feeType) {
this.feeType = feeType;
}
public int getFeeUserType() {
return feeUserType;
}
public void setFeeUserType(int feeUserType) {
this.feeUserType = feeUserType;
}
public String getFeeCode() {
return feeCode;
}
public void setFeeCode(String feeCode) {
this.feeCode = feeCode;
}
public String getValidTime() {
return validTime;
}
public void setValidTime(String validTime) {
this.validTime = validTime;
}
public String getAtTime() {
return atTime;
}
public void setAtTime(String atTime) {
this.atTime = atTime;
}
public String getSrcTermID() {
return srcTermID;
}
public void setSrcTermID(String srcTermID) {
this.srcTermID = srcTermID;
}
/**
* 以二进制发送短信
* @param chargeTermID 计费手机号
* @param destTermID 目的手机号
* @param content 字节内容
* @return 返回完整的返回信息,操作成功时返回:“发送成功”,其余都为错误的情况
* */
public String send(
final String chargeTermID,
final String destTermID,
final byte[]content){
String resultInfo="100";
//.....
return resultInfo;
}
}
[b]3. 编写Spring配置文件,具体内容如下:[/b]
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"
default-autowire="byName" default-lazy-init="true">
<!-- 构造方法注入 -->
<bean id="SMSSender1" class="amigo.spring.chapter16.SMSSender1">
<constructor-arg index="0">
<value>0</value>
</constructor-arg>
<constructor-arg index="1">
<value>1</value>
</constructor-arg>
<constructor-arg index="2">
<value>1</value>
</constructor-arg>
<constructor-arg index="3">
<value>11111</value>
</constructor-arg>
<constructor-arg index="4">
<value>15</value>
</constructor-arg>
<constructor-arg index="5">
<value>01</value>
</constructor-arg>
<constructor-arg index="6">
<value>01</value>
</constructor-arg>
<constructor-arg index="7">
<value>000001</value>
</constructor-arg>
<constructor-arg index="8">
<value></value>
</constructor-arg>
<constructor-arg index="9">
<value></value>
</constructor-arg>
<constructor-arg index="10">
<value>13555555555</value>
</constructor-arg>
</bean>
</beans>
[b]4. 编写测试类TestSMSSender1.java[/b]
package amigo.spring.chapter16;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class TestSMSSender1 {
public static void main(String[] args){
ClassPathResource res = new ClassPathResource("applicationContext.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);
SMSSender1 sender1 = (SMSSender1)factory.getBean("SMSSender1");
System.out.println(sender1.getSrcTermID());
}
}
最后结果打印出了srcTermID的值为:13555555555
[size=large][b]六. 注入方式 ---setter方法注入[/b][/size]
[b]1. 编写短信类SMSSender2.java(此类与SMSSender1.java略有不同,它去掉了构造函数)[/b]
package amigo.spring.chapter16;
/**
* 短信发送
* */
public class SMSSender2 {
/**0消息类型*/
int msgType;
/**1是否需要状态报告*/
int needReport;
/**1消息发送优先级别*/
int msgLevel;
/**11111 业务代码*/
String serviceID;
/**15消息格式*/
int msgFormat;
/**01计费类型*/
String feeType;
/**00用户类型*/
int feeUserType;
/**123456计费代码*/
String feeCode;
/**有效期*/
String validTime;
/**定时发送时间*/
String atTime;
/**11111源用户号码*/
String srcTermID;
public int getMsgType() {
return msgType;
}
public void setMsgType(int msgType) {
this.msgType = msgType;
}
public int getNeedReport() {
return needReport;
}
public void setNeedReport(int needReport) {
this.needReport = needReport;
}
public int getMsgLevel() {
return msgLevel;
}
public void setMsgLevel(int msgLevel) {
this.msgLevel = msgLevel;
}
public String getServiceID() {
return serviceID;
}
public void setServiceID(String serviceID) {
this.serviceID = serviceID;
}
public int getMsgFormat() {
return msgFormat;
}
public void setMsgFormat(int msgFormat) {
this.msgFormat = msgFormat;
}
public String getFeeType() {
return feeType;
}
public void setFeeType(String feeType) {
this.feeType = feeType;
}
public int getFeeUserType() {
return feeUserType;
}
public void setFeeUserType(int feeUserType) {
this.feeUserType = feeUserType;
}
public String getFeeCode() {
return feeCode;
}
public void setFeeCode(String feeCode) {
this.feeCode = feeCode;
}
public String getValidTime() {
return validTime;
}
public void setValidTime(String validTime) {
this.validTime = validTime;
}
public String getAtTime() {
return atTime;
}
public void setAtTime(String atTime) {
this.atTime = atTime;
}
public String getSrcTermID() {
return srcTermID;
}
public void setSrcTermID(String srcTermID) {
this.srcTermID = srcTermID;
}
/**
* 以二进制发送短信
* @param chargeTermID 计费手机号
* @param destTermID 目的手机号
* @param content 字节内容
* @return 返回完整的返回信息,操作成功时返回:“发送成功”,其余都为错误的情况
* */
public String send(
final String chargeTermID,
final String destTermID,
final byte[]content){
String resultInfo="100";
//.....
return resultInfo;
}
}
[b]2.修改配置文件applicationContext.xml
添加如下bean:[/b]
<!--setter 方式注入 -->
<bean id="SMSSender2" class="amigo.spring.chapter16.SMSSender2">
<property name="msgType" value="0"/>
<property name="needReport" value="1"/>
<property name="msgLevel" value="1"/>
<property name="serviceID" value="11111"/>
<property name="msgFormat" value="15"/>
<property name="feeType" value="01"/>
<property name="feeUserType" value="01"/>
<property name="feeCode" value="000001"/>
<property name="validTime" value=""/>
<property name="atTime" value=""/>
<property name="srcTermID" value="13555555555"/>
</bean>
[b]3.编写测试类:[/b]
package amigo.spring.chapter16;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class TestSMSSender2 {
public static void main(String[] args){
ClassPathResource res = new ClassPathResource("applicationContext.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);
SMSSender2 sender2 = (SMSSender2)factory.getBean("SMSSender2");
System.out.println(sender2.getSrcTermID());
}
}
[size=large][b]七.注入方式---接口注入[/b][/size]
[b] 1.编写接口类UserBean.java[/b]
package amigo.spring.chapter16;
import java.util.List;
public interface UserBean {
public List getUserList();
public void saveUser(String loginName,String password);
public void updateUser(String loginName,String password);
public void deleteUser(String loginName);
}
[b]2.编写实现类UserBeanImpl.java[/b]
package amigo.spring.chapter16;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class UserBeanImpl implements UserBean {
@Override
public void deleteUser(String loginName) {
// TODO Auto-generated method stub
}
@Override
public List getUserList() {
List userList = new ArrayList();
Map userMap1 = new HashMap();
userMap1.put("loginName", "amigo");
userMap1.put("password","xiexingxing");
Map userMap2 = new HashMap();
userMap2.put("loginName", "xiexingxing");
userMap2.put("password", "xiexingxing");
userList.add(userMap1);
userList.add(userMap2);
return userList;
}
@Override
public void saveUser(String loginName, String password) {
// TODO Auto-generated method stub
}
@Override
public void updateUser(String loginName, String password) {
// TODO Auto-generated method stub
}
}
[b]3.编写接口注入类InterfaceInject.java[/b]
package amigo.spring.chapter16;
public class InterfaceInject {
private UserBean userBean;
public void setUserBean(UserBean userBean){
this.userBean=userBean;
}
public void printUserListSize(){
System.out.println("userList's size is:"+userBean.getUserList().size());
}
}
[b]4.编写Spring配置文件(在原有的配置文件上加上如下的bean)[/b]
<!-- 接口方式注入 -->
<bean id="userBean" class="amigo.spring.chapter16.UserBeanImpl" />
<bean id="InterfaceInject" class="amigo.spring.chapter16.InterfaceInject">
<property name="userBean">
<ref local="userBean"/>
</property>
</bean>
[b]5.编写测试类[/b]
package amigo.spring.chapter16;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
/**
* 接口注入
* */
public class TestInterfaceInject {
public static void main(String[] args){
ClassPathResource res = new ClassPathResource("applicationContext.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);
InterfaceInject inject = (InterfaceInject) factory.getBean("InterfaceInject");
inject.printUserListSize();
}
}
[b]
[size=large]八. Bean属性及构造器参数[/size][/b]
下面来看一个直接量使用的举例,在DbConnection类中,driverClassName(驱动器类名)、url(数据库连接路径)、username(数据库用户名)和password(数据库密码)属性都需要在Spring中进行配置。
[b]1. 配置直接量[/b]
(1) 编写测试类:DataSource.java
package amigo.spring.ioc.beanproperties;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
/**
* 演示直接量的使用
* @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
* @Creation date: Sep 13, 2008 - 1:39:02 PM
*/
public class DataSource {
/** 驱动器类名. */
private String driverClassName;
/** 数据库连接路径. */
private String url;
/** 数据库用户名. */
private String username;
/** 数据库密码. */
private String password;
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
public void setUrl(String url) {
this.url = url;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public String getDriverClassName() {
return driverClassName;
}
public String getUrl() {
return url;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public Object getConnection() {
//...省略实现
return null;
}
public void close() {
//...省略实现
}
/**
* 测试方法.
* @param args
*/
public static void main(String[] args) {
ClassPathResource res1 = new ClassPathResource(
"beanproperties.xml");
XmlBeanFactory factory = new XmlBeanFactory(res1);
DataSource dbConnection = (DataSource) factory.getBean("dataSource");
System.out.println("driverClassName=" + dbConnection.getDriverClassName());
System.out.println("url=" + dbConnection.getUrl());
System.out.println("username=" + dbConnection.getUsername());
System.out.println("password=" + dbConnection.getPassword());
}
}
(2) 编写配置文件:Beanproperties.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-2.0.xsd">
<!-- 直接量. -->
<bean id="dataSource"
destroy-method="close"
class="amigo.spring.ioc.beanproperties.DataSource">
<!-- 需要在amigo.spring.ioc.beanproperties.DataSource类中有相应的setter方法. -->
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/test</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>123</value>
</property>
</bean>
</beans>
[b]2. 引用其他的bean[/b]
(1) 编写测试类:User.java
package amigo.spring.ioc.beanproperties;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
/**
* 展示在Spring配置文件中如何引用其它的bean.
* @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
* @Creation date: Sep 13, 2008 - 2:15:26 PM
*/
public class User {
/** 用户名.*/
private String username;
/** 密码. */
private String password;
/** 所属部门. */
private Dept dept;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Dept getDept() {
return dept;
}
public void setDept(Dept dept) {
this.dept = dept;
}
/**
* 测试方法.
*/
public static void main(String[] args) {
ClassPathResource res1 = new ClassPathResource(
"beanproperties.xml");
XmlBeanFactory factory = new XmlBeanFactory(res1);
User user = (User) factory.getBean("user");
System.out.println("用户所属部门名称=" + user.getDept().getName());
}
}
(2) 编写依赖类:Dept.java
package amigo.spring.ioc.beanproperties;
/**
* 展示在Spring配置文件中如何引用其它的bean.
* @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
* @Creation date: Sep 13, 2008 - 2:17:04 PM
*/
public class Dept {
/** 部门名称. */
private String name;
/** 状态. */
private int status;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
}
(3)修改配置文件:beanproperties.
<!-- 引用其它的bean. -->
<bean id="dept" class="amigo.spring.ioc.beanproperties.Dept">
<property name="name">
<value>软件研发部</value>
</property>
</bean>
<bean id="user" class="amigo.spring.ioc.beanproperties.User">
<property name="dept">
<ref local="dept" />
</property>
</bean>
[b]3. 内部bean(内部bean是指在一个bean的<property/>或<constructor-arg/>元素中使用<bean/>元素定义的bean)[/b]
(1)编写测试类:OuterBean.java
package amigo.spring.ioc.beanproperties;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
/**
* 演示Spring中内部bean的配置.
* @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
* @Creation date: Sep 13, 2008 - 2:53:59 PM
*/
public class OuterBean {
private InnerBean innerBean;
public InnerBean getInnerBean() {
return innerBean;
}
public void setInnerBean(InnerBean innerBean) {
this.innerBean = innerBean;
}
/**
* 测试方法.
*/
public static void main(String[] args) {
ClassPathResource res1 = new ClassPathResource(
"beanproperties.xml");
XmlBeanFactory factory = new XmlBeanFactory(res1);
OuterBean outerBean = (OuterBean) factory.getBean("outerBean");
System.out.println("内部bean的name属性值为=" + outerBean.getInnerBean().getName());
}
}
(2)编写内部bean类:InnerBean.java
package amigo.spring.ioc.beanproperties;
/**
* 内部bean.
* @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
* @Creation date: Sep 13, 2008 - 2:54:46 PM
*/
public class InnerBean {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
(3)修改配置文件:beanproperties.xml
<!-- 内部bean -->
<bean id="outerBean" class="amigo.spring.ioc.beanproperties.OuterBean">
<property name="innerBean">
<bean class="amigo.spring.ioc.beanproperties.InnerBean">
<property name="name">
<value>我是内部bean</value>
</property>
</bean>
</property>
</bean>
[b]4. 在配置文件中配置集合[/b]
(1) 编写测试类:CollectionTest.java
package amigo.spring.ioc.beanproperties;
import java.util.*;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
/**
* Spring配置集合.
* @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
* @Creation date: Sep 13, 2008 - 3:10:18 PM
*/
public class CollectionTest {
private List userList;
private Set emailSet;
private Map typeMap;
private Properties configProperties;
public List getUserList() {
return userList;
}
public void setUserList(List userList) {
this.userList = userList;
}
public Set getEmailSet() {
return emailSet;
}
public void setEmailSet(Set emailSet) {
this.emailSet = emailSet;
}
public Map getTypeMap() {
return typeMap;
}
public void setTypeMap(Map typeMap) {
this.typeMap = typeMap;
}
public Properties getConfigProperties() {
return configProperties;
}
public void setConfigProperties(Properties configProperties) {
this.configProperties = configProperties;
}
/**
* 测试方法.
*/
public static void main(String[] args) {
ClassPathResource res1 = new ClassPathResource(
"beanproperties.xml");
XmlBeanFactory factory = new XmlBeanFactory(res1);
CollectionTest test = (CollectionTest) factory.getBean("collectionTest");
// List类型
List userList = test.getUserList();
for (int i = 0, len = userList.size(); i < len; i++) {
System.out.println("用户信息:" + (String) userList.get(i));
}
// Set类型
Set emailSet = test.getEmailSet();
Iterator ite = emailSet.iterator();
while(ite.hasNext()) {
System.out.println("Email信息:" + ite.next());
}
// Map类型
Map typeMap = test.getTypeMap();
System.out.println("id为1000的类型的名称为=" + typeMap.get("1000"));
// Properties类型
Properties configProperties = test.getConfigProperties();
System.out.println("usernmae属性为:" + configProperties.getProperty("username"));
}
}
(3) 修改配置文件:beanproperties.xml
<!-- 集合 -->
<bean id="collectionTest" class="amigo.spring.ioc.beanproperties.CollectionTest">
<!-- List类型 -->
<property name="userList">
<list>
<value>阿蜜果</value>
<value>amigo</value>
<value>谢星星</value>
</list>
</property>
<!-- Set类型 -->
<property name="emailSet">
<set>
<value>administrator@amigo.com</value>
<value>xiexingxing1121@126.com</value>
<value>amigo@126.com</value>
</set>
</property>
<!-- Map类型 -->
<property name="typeMap">
<map>
<entry>
<key>
<value>1000</value>
</key>
<value>时尚购物</value>
</entry>
<entry>
<key>
<value>1001</value>
</key>
<value>精彩旅游</value>
</entry>
</map>
</property>
<property name="configProperties">
<props>
<prop key="username">阿蜜果</prop>
<prop key="password">3344</prop>
</props>
</property>
</bean>