14.1 初探Spring
14.1.1 Spring简介
本章来学习另一个流行框架Spring,并学习使用Struts 2整合Spring进行开发。简单来说,Spring是一个轻量级的IoC和AOP容器框架。通过其核心的依赖注入机制,以及AOP的声明式事务管理,与持久层框架以及与其他的MVC框架整合,为企业应用提供了一个轻量级的解决方案。
SSH整合开发,就是指整合Struts、Spring、Hibernate来进行开发。SSH整合开发是一个非常好的企业级开发方案。使用Spring的IoC容器来负责创建和管理组件,其中组件包括前端的业务控制器、中间的业务逻辑组件以及最底层的DAO组件。这些组件都处于Spring的IoC容器管理,从而大大降低各组件之间的耦合度。
Spring框架有如下优势。
❑ 轻量级,非侵入式:基于Spring开发应用时新建的类一般都无需继承Spring中的类。
❑ 反向控制:又称为依赖注入和IoC。使用方向控制,对象是被动接收依赖类而不是主动去找,从而降低了耦合度。
❑ 面向切面:又称为AOP。使用面向切面编程,可以将业务逻辑从系统服务中抽取出来,实现内聚开发。
❑ Spring是免费的、开放源代码的。
❑ Spring拥有众多社区支持。
14.1.2 下载和安装Spring
首先登录Spring框架官方站点http://www.springframework.org,如图14.1所示。在下载列表中选择下载Spring 2.0.8版本。
安装Spring非常简单,如果开发Java程序则只需将Spring解压文件夹的disk目录下的“spring.jar”添加到ClassPath下。如果开发Web应用则只需将“spring.jar”拷贝到Web应用的WEB-INF\lib目录下。如果应用需要使用到其他第三方的JAR,则还需将其添加到ClassPath下或拷贝到Web应用的WEB-INF\lib目录下。
图14.1 Hibernate官方站点
14.1.3 Spring的IoC应用
在介绍Spring的依赖注入之前,首先来看一个普通的Java应用。首先定义一个Person接口,该接口中包含一个go()方法,代码如下所示。
package net.hncu.demo01; public interface Person { //Person接口包含一个go方法 public void go(); }
新建Student类,该类实现Person接口,并实现Person接口中的go()方法,代码如下所示。
package net.hncu.demo01; public class Student implements Person { //实现Person接口中的go方法 public void go(){ System.out.println("去教室上课"); } }
新建Teacher类,该类实现Person接口,并实现Person接口中的go()方法,代码如下所示。
package net.hncu.demo01; public class Teacher implements Person{ //实现Person接口中的go方法 public void go(){ System.out.println("去教室讲课"); } }
在主程序中创建Teacher类和Student类实例,并调用实例的go()方法,代码如下所示。
package net.hncu.demo01; public class Test { public static void main(String[] args) { //创建Teacher类实例 Teacher teacher = new Teacher(); //调用Teacher实例的go方法 teacher.go(); //创建Student类实例 Student student = new Student(); //调用Student实例的go方法 student.go(); } }
运行该Java程序,在控制台中打印输出如下语句。
去教室讲课 去教室上课
前面这个示例中,直接通过Teacher类和Student类创建其实例对象,代码耦合度高。如何才能降低主程序和组件之间的耦合度呢?
可以通过创建工厂类来降低耦合度。在工厂类中定义两个方法,分别用来返回Teacher类和Student类实例,代码如下所示。
package net.hncu.demo01; public class Factory { //返回Teacher类实例 public static Person getTeacher(){ return new Teacher(); } //返回Student类实例 public static Person getStudent(){ return new Student(); } }
这样在主程序中就可以通过调用工厂类中的方法来获得Teacher类和Student类实例,代码如下所示。
package net.hncu.demo01 public class Test { public static void main(String[] args) { //通过工厂获得Teacher类实例 Person teacher = Factory.getTeacher(); //调用Teacher实例的go方法 teacher.go(); //通过工厂获得Student类实例 Person student = Factory.getStudent(); //调用Student实例的go方法 student.go(); } }
这样主程序不会直接与Teacher类和Student类耦合,而只是与Person接口耦合,这样大大降低了类之间的耦合度。
下面来看如何直接通过Spring容器来生成Java实例。首先需要让Spring容器知道创建哪些类的实例,Spring提供以配置文件的方式来管理Java实例,添加配置文件,代码如下所示。
<? 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"> <! -- 创建Student实例 --> <bean id="student" class="net.hncu.demo01.Student"></bean> <! -- 创建Teacher实例 --> <bean id="teacher" class="net.hncu.demo01.Teacher"></bean> </beans>
在主程序中直接取得Spring容器中的Teacher类和Student类实例,并调用实例的go()方法,代码如下所示。
package net.hncu.demo01; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.core.io.ClassPathResource; public class Test { public static void main(String[] args) { //创建ClassPathResource实例 ClassPathResource isr = new ClassPathResource("beans1.xml"); //创建XmlBeanFactory实例 XmlBeanFactory factory = new XmlBeanFactory(isr); //从Spring容器中获得Teacher实例 Person teacher = (Person) factory.getBean("teacher"); teacher.go(); //从Spring容器中获得Student实例 Person student = (Person) factory.getBean("student"); student.go(); } }
主程序不会直接与Teacher类和Student类耦合,而只是与Person接口耦合,大大降低了类之间的耦合度。
Spring的IoC容器就是一个大的工厂,当需要什么对象时,直接从里面拿即可。其实Spring最大的好处在于可以自动地注入所需的实例。