引用:http://hi.baidu.com/y0h0001/item/ad230b4bbe91e32e6dc2f017
例题 16-2使用构造函数配置Bean对象属性
package ch16;
import java.util.*;
public class TestConstructor{
private TestProperty prop;
private String name;
private int age;
public TestConstructor(String name,TestProperty prop,int age) {
this.name=name;
this.age=age;
this.prop=prop;
}
public TestProperty getProp() { return this.prop;}
public String getName() {return name;}
public int getAge() {return this.age;}
}
可以在XML文件中这样配置该Bean:
<bean id="mycon" class="ch16.TestConstructor">
<constructor-arg index="0">
<value>赵云</value>
</constructor-arg>
<constructor-arg index="1">
<ref bean="myproperty"/>
</constructor-arg>
<constructor-arg index="2">
<value>39</value>
</constructor-arg>
</bean>
4.让 Spring 完成自动配置
可以采用下面的<bean>元素让Spring自动装配Bean对象的属性(自动为Bean对象的属性寻找和设定值):
<beanid="mybean"class="包名.类名"autowire="自动类型">
</bean>
自动类型有下面几种方式:
byName:在 IoC 容器中寻找与需要自动装配的属性的属性名相同的bean或id,如果没有找到,则这个属性未被装配上。
byType:在 IoC 容器中寻找与需要自动装配的属性的类型相同的bean或id,如果没有找到,则这个属性未被装配上。
constructor:在 IoC 容器中寻找与需要自动装配的bean的构造函数参数一致的一个或多个bean,如果没有找到,则抛出异常。
autodetect:首先尝试constructor方式来自动装配,然后再使用byType方式。
如果某个bean不设置autowire属性,则默认为手动装配其全部属性,如果需要对所有的bean都设置为自动装配,可以在<beans>元素中设置default-autowire属性,该属性的取值仍然是上面的4个值之一。
自动装配Bean时可能带来不确定的问题,例如使用byType装配方式时,可能会同时发现两个相同类型的对象,这时则不可确定该用哪一个对象来装配。所以可能混合采用自动装配和手动装配更好,例如:对某个Bean设置为自动装配,而对其某个属性则手动设置其取值,例如:
<beanid="mybean"class="abc.MyBean"autowire="byType">
<property name="name">
<value>zhangping</value>
</property>
</bean>
通过这样的配置,对mybean中的name属性进行了手动装配,而对name属性之外的其它属性都采用byType方式的自动装配。
16.3 用Spring开发Java Web应用
下面的示例演示了如何使用Spring框架开发简单的Web应用程序,本示例在浏览器页面中显示 "Hello , Spring!"。
创建一个类HelloBean,文件名为HelloBean.java,这是第一个组件,是一个简单的JavaBean,用来向新的用户打招呼,代码如下:
package ch16;
public class HelloBean {
private String helloWord="Hello,World!";
public voidsetHelloWord(String helloWord){this.helloWord=helloWord;}
public StringgetHelloWord() {return helloWord;}
}
HelloBean类有预设的文字"Hello,World",也可以使用setter方法(setHelloWord)设定新的问候语。
编写HelloBean类的配置文件bean.xml(放置在WEB-INF/classes目录中),内容如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="helloBean" class="ch16.HelloBean">
<property name="helloWord">
<value>Hello,Spring!</value>
</property>
</bean>
</beans>
在bean.xml中定义了JavaBean的别名与来源类别,<property>元素中设定了希望注入(保存)到Bean中的新的问候语,bean.xml文件必须位于WEB-INF/classes目录中。对于单机版本的程序,应该放在工作目录下的classes目录中,然后通过FileInputStream读取beam.xml文件。
再编写一个单机版本地的测试程序,测试Spring框架是否能正常运行:
package ch16;
import java.io.*;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.InputStreamResource;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
public class TestHelloWorld{
public static void main(String[] args) throws Exception{
XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("bean.xml"));
HelloBean hello=(HelloBean)factory.getBean("helloBean");
System.out.println(hello.getHelloWord());
}
}
也可以编写一个JSP页面 hello.jsp 来测试上面的Spring框架配置是否正确:
<%@ page import="org.springframework.core.io.*" %>
<%@ page import="org.springframework.beans.factory.xml.XmlBeanFactory" %>
<%@ page import="org.springframework.beans.factory.BeanFactory" %>
<%@ page import="ch16.*" %>
<%
XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("bean.xml"));
HelloBean hello=(HelloBean)factory.getBean("helloBean");
%>
<h1><%=hello.getHelloWord() %> </h1>
通过setter所保留的接口,使用setter injection来完成依赖注入,而不是将问候语(Hello Spring )直接写在程序中。BeanFactory是整个Spring框架的重点所在,整个Spring的核心都围绕着它,在这里使用的是XmlBeanFactory,负责读取XML形式的配置文件,当然也可以使用properties形式的配置文件。BeanFactory读取Bean的组态设定并完成维护关系后,可以通过getBean("别名")方法并指定Bean的别名来取得Bean的实例(对象)。如果想改变问候语,则只需要修改bean.xml文件,并不需要对程序代码进行任何修改,这就意味着:如果想修改对象之间的依赖关系,只需要修改组装配置文件,而不需要对组件的程序代码做任何修改。
16.4 Spring数据源配置
16.4.1 环境和背景
为了从数据库中取得数据,首先要获取一个与数据库的连接,Spring框架通过组装一个实现了DataSource接口的对象来完成这个工作,DataSource接口是JDBC规范的一部分,它被视为一个通用的数据库连接工厂。通过使用DataSource、Container或Framework,可以将数据库连接池以及事务管理的细节从应用程序的代码中分离出去。
在使用Spring JDBC时,既可以通过JNDI获得数据源,也可以自行配置数据源(使用Spring提供的 DataSource 接口的实现类,DriverManagerDataSource 就是 DataSource 的一个实现类)。使用后者可以更方便地脱离Web容器进行单元测试。这里将使用DriverManagerDataSource。DataSource接口有很多实现类,使用DriverManagerDataSource和以前获得一个JDBC连接的做法相同,首先必须指定JDBC驱动程序的全限定名,这样DriverManagerDataSource才能加载JDBC驱动程序类,接着提供一个数据库URL和用户名以及密码。
Spring框架提供的DriverManagerDataSource类实现了DataSource接口,该类可以根据在Spring的组装配置文件定义的<bean>得到一个DataSource对象。
16.4.2 创建项目
在Web应用的WEB-INF/classes目录中编写Spring框架的数据库配置文件DBContext.xml,文件内容如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="rptds" destroy-method="close" class=
"org.springframework.jdbc.datasource.DriverManagerDataSource" >
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/study</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>zym</value>
</property>
</bean>
</beans>
在上面的这个数据库配置文件中,定义了一个DataSource装配(名称为rptds),这样,就可以利用Spring框架的IoC容器来自动装配一个数据源对象,提供给其他组件来使用。
16.4.3 创建数据库环境
在MySQL中创建数据库st,在st数据库中创建一张表:
create tablet_user(id int(11) not null auto_increment,
firstname varchar(50) default NULL,
lastname varchar(50) default NULL,
zipcode varchar(50) default NULL,
tel varchar(50) default NULL,
address varchar(50) default NULL,
primary key(id));
插入记录:insert into t_user(firstname,lastname,zipcode,tel,address)
values('haha','hehe','23444','1356789000','阿拉伯');
insert into t_user(firstname,lastname,zipcode,tel,address)
values('lei','aaa','450000','1390007888','北京');
16.4.4 Spring Bean容器环境获取工具类ContextHelper.java
在这个类中,读取Spring框架的配置文件DBContext.xml,生成Spring框架的上下文环境。
package ch16;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public final class ContextHelper{
private static ClassPathXmlApplicationContext_ctx;
//类初始化器
static {
//读取spring配置文件,生成Spring上下文环境
_ctx=new ClassPathXmlApplicationContext("DBContext.xml");
}
//私有构造函数
private ContextHelper() {}
//得到Spring框架的上下文
public static ClassPathXmlApplicationContextgetContext() {
return_ctx;
}
}