在分层的web应用系统中,通常将数据操作分为dao数据层和service业务逻辑层,dao层负责对数据的操作,servlet或action通过service层对数据进行读写,而service层对数据的读写依赖于dao 层对数据的操作,因此存在着类之间的依赖。下面我们通过模拟实验理解不同技术对依赖关系的处理。
例1.在传统的模式中,依赖关系是通过构造对象的方式实现的。
创建如下三个类,模拟从dao到service的功能实现:
class dao_class{
public String selectUser(String user){
return "找到了"+user;
}
}
class service_class{
dao_class dao=new dao_class();
public String findUser(String username){
return dao.selectUser(username);
}
}
public class dao_service_controller {
public static void main(String []args) {
service_class service=new service_class();
System.out.println(service.findUser("张三"));
}
}
运行结果为:找到了张三。
程序中,语句:dao_class dao=new dao_class();使得service_class严重“依赖”dao_class,形成紧密的耦合关系,不符合现代编程理念。
例2.传统的通过接口方式减轻service_class和dao_class耦合程度。
interface dao_interface{
String selectUser(String user);
}
class dao_class implements dao_interface{
public String selectUser(String user){
return "找到了"+user;
}
}
class service_class implements service_interface{
dao_interface dao;
public void setDao(dao_interface dao){
this.dao=dao;
}
public String findUser(String username){
return dao.selectUser(username);
}
}
public class dao_service_controller {
public static void main(String []args) {
service_class service=new service_class();
dao_interface dao=new dao_class();
service.setDao(dao);
System.out.println(service.findUser("张三"));
}
}
通过接口编程,方法:
public void setDao(dao_interface dao){
this.dao=dao;
}
使得service_class和dao_class耦合程度大大降低,但是dao_service中的语句:
dao_interface dao=new dao_class();
service.setDao(dao);
使得dao_service_controller(模拟控制器)和dao_class发生了依赖,因此这种方式也没有解决耦合紧密的问题。
例3. 在例2的基础上通过依赖注入的方式解决:
(1)首先在项目中添加spring库,如图(本例基于NetBeans7.0):
(2)新建“Spring XML配置文件”,命名为“mySpringCfg.xml”:
在步骤3中选择context的Spring名称空间:
(3)在mySpringCfg.xml文件中加入下面语句:
<bean id="daoClass" class="dao_class"/>
<bean id="serviceClass" class="service_class">
<property name="dao">
<ref local="daoClass"/>
</property>
</bean>
表示程序中有两个bean:daoClass和serviceClass,分别代表dao_class 类和service_class类,而“serviceClass”通过“接口”参数“dao”和“daoClass”发生依赖。
(4)修改dao_service _controller类:
public class dao_service _controller{
public static void main(String []args) {
ApplicationContext ctx
=new FileSystemXmlApplicationContext("src/mySpringCfg.xml");
service_class service=(service_class)ctx.getBean("serviceClass");
System.out.println(service.findUser("张三"));
}
}
其中语句:
ApplicationContext ctx=new FileSystemXmlApplicationContext("src/mySpringCfg.xml");
表示引入Spring XML配置文件:“mySpringCfg.xml”创建上下文ctx。
语句:
service_class service=(service_class)ctx.getBean("serviceClass");
表示通过上下文ctx创建service_class对象,在创建对象时,通过接口“dao”引用dao_class对象,其关联语句分别为:
service_class类中的语句:
dao_interface dao;
public void setDao(dao_interface dao){
this.dao=dao;
}
注意接口成员的名称;
配置文件mySpringCfg.xml中的语句:
<property name="dao">
<ref local="daoClass"/>
</property>
其余的类和接口均不需要变动。可以看到,service_class类只和接口dao_interface成员dao发生关联,和dao_Class类的依赖是通过配置文件发生的,是在创建对象时“注入”的。