一、Spring包结构图:
二、 First Step
举个简单的例子:(使用WSAD的包结构)
Java Souce
com
……..test
………domain
Action.java
LowerAction.java
UpperAction.java
………service
TestQuickStart.java
Web Content
WEB-INF
classes
bean.xml
log4j.properties
开始之前还需要把必要的包copy过去,包括spring.jar,log4j.jar, commons-logging.jar
来看具体代码:
Action.java(是一个接口)
package com.sscm.test.domain;
public interface Action {
public String execute(String str);
}
LowerAction.java (实现类)
package com.sscm.test.domain;
public class LowerAction implements Action{
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String execute(String str){
return (getMessage()+str).toLowerCase();
}
}
UpperAction.java
package com.sscm.test.domain;
public class UpperAction implements Action{
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String execute(String str){
return (getMessage()+str).toUpperCase();
}
}
再来看Spring的配置文件(bean.xml)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<description>Spring Quick Start</description>
<bean id="TheAction"
class="com.sscm.test.domain.UpperAction">
<property name="message">
<value>HeLLo</value>
</property>
</bean>
</beans>
实现代码:TestQuickStart.java
package com.sscm.test.service;
import com.sscm.test.domain.*;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestQuickStart {
public static void TestQuickStart1() {
try{
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("/bean.xml");
Action action = (Action) ctx.getBean("TheAction");
//System.out.println("aaa");
System.out.println(action.execute(" Rod Johnson"));
}catch(Exception e){
}
}
public static void main(String[] args){
TestQuickStart1();
}
}
运行测试代码,我们看到控制台输出:
……
HELLO ROD JOHNSON
示例完成。
仔细观察一下上面的代码,可以看到:
1. 我们的所有程序代码中(除测试代码之外),并没有出现Spring中的任何组件。
2. UpperAction和LowerAction的Message属性均由Spring通过读取配置文件(bean.xml)动
态设置。
3. 客户代码(这里就是我们的测试代码)仅仅面向接口编程,而无需知道实现类的具体名称。同时,
我们可以很简单的通过修改配置文件来切换具体的底层实现类。
上面所说的这些,对于我们的实际开发有何帮助?
Ø 首先,我们的组件并不需要实现框架指定的接口,因此可以轻松的将组件从Spring中脱离,甚
至不需要任何修改(这在基于EJB框架实现的应用中是难以想象的)。
Ø 其次,组件间的依赖关系减少,极大改善了代码的可重用性。
使用Spring大大降低了组件之间的耦合,
实现了组件真正意义上的即插即用。这也是Spring最具价值的特性之一。
Ø 面向接口编程。
诚然,即使没有Spring,实现面向接口的设计也不困难。Spring对于面向接口设计的意义,在
于它为面向接口编程提供了一个更加自然的平台。基于Spring开发,程序员会自然而然倾向于
使用接口来定义不同层次之间的关联关系,这种自发的倾向性,来自于Spring所提供的简单舒
适的依赖注入实现。Spring使得接口的定义和使用不再像传统编码过程中那么繁琐(传统编码
过程中,引入一个接口,往往也意味着同时要引入一个Factory类,也许还有一个额外的配置文
件及其读写代码)。
三、 Spring基础语义
1.控制反转(IoC = Inversion of Control),就是由容器控制程序之间的关系,而非传统实现中,由程序代码直接操控。这也就是所谓“控制反转”的概念所在:控制权由应用代码中转到了外部容器,控制权的转移,是所谓反转。
2.依赖注入(DI = Dependency Injection),即组件之间的依赖关系由容器在运行期决定,形象的来说,即由容器动态的将某种依赖关系注入到组件之中。
对上面抽象概念的理解,可以举个简单例子:
使用U盘或者移动硬盘从laptop中copy数据。,笔记本电脑与外围存储设备通过预先指定的一个接口(USB)相连,对于笔记本而言,只是将用户指定的数据发送到USB接口,而这些数据何去何从,则由当前接入的USB设备决定。在USB设备加载之前,笔记本不可能预料用户将在USB接口上接入何种设备,只有USB设备接入之后,这种设备之间的依赖关系才开始形成。
对应上面关于依赖注入机制的描述,在运行时(系统开机,USB 设备加载)由容器(运行在笔记本
中的Windows操作系统)将依赖关系(笔记本依赖USB设备进行数据存取)注入到组件中(Windows
文件访问组件)。
这就是依赖注入模式在现实世界中的一个版本。
依赖注入机制减轻了组件之间的依赖关系,同时也大大提高了组件的可移植性,这意味着,组件得到重用
的机会将会更多。
3. Spring Bean封装机制
Spring的核心是一个DI容器。提供一种无倾入性的高扩展性框架。。即无需代码中涉及Spring专有类,即可将其纳入Spring容器进行管理。
Spring引入java的Reflection机制,通过动态调用的方式避免了硬编码方式的约束。其核心组件是BeanFactory,以次做为依赖注入的实现基础。org.springframework.beans包中包括了这些核心组件的实现类,核心中的核心为BeanWrapper和BeanFactory类。
通过BeanWrapper,我们可以无需在编码时就指定JavaBean的实现类和属性值,通过在配置文件
加以设定,就可以在运行期动态创建对象并设定其属性(依赖关系)。
Bean Factory负责根据配置文件创建Bean实例,可以配置的项目有:
1. Bean属性值及依赖关系(对其他Bean的引用)
2. Bean创建模式(是否Singleton模式,即是否只针对指定类维持全局唯一的实例)
3. Bean初始化和销毁方法
4. Bean的依赖关系
如bean.xml。
BeanWrapper实现了针对单个Bean的属性设
定操作。而BeanFactory则是针对多个Bean的管理容器,根据给定的配置文件,BeanFactory从中读取
类名、属性名/值,然后通过Reflection机制进行Bean加载和属性设定。
ApplicationContext覆盖了BeanFactory的所有功能,并提供了更多的特性。
5. Spring 高级特性
基于Web的MVC1框架在J2EE的世界内空前繁荣, 目前比较好的MVC,老牌的有Struts、Webwork。新兴的MVC 框架有Spring MVC、
Tapestry、JSF等。这些大多是著名团队的作品,另外还有一些边缘团队的作品,也相当出色,
如Dinamica、VRaptor等。
如何选择一个合适的框架?
主要考虑技术成熟度,替代成本,与特定容器的耦合度等。