现在开始写写Spring,Spring它是一个非常优秀的 框架,在之前我已经写过Struts和Hibernate,大家知道现在流行的框架体系结构就是Struts + Spring + Hibernate,现在也有的公司用jsf+ajax代替struts, 就是用来做用户界面层UI。一般是Struts导过来,它有一个表单Bean,以前表单的action就用Struts来做,但现在有了Spring,就由Spring来接手,以后就是由Spring的反转控制以及它的面向切面性,来接手Struts里面的一些东西,也包括日志服务!
Spring 是一种多层的JAVAEE应用程序框架,其核心就是提供一种新的机制管理业务对象及其依赖关系。例如IOC(反转控制)也称为依赖注入,AOP(面向切面编程)!
我们先来看一张图片:
上图显示出Spring的七个模块,第一个AOP主要是面向切面性部分,先简单的介绍下什么是面向切面性,其实面向切面性是面向对象性中的一种特殊情况,它其实也是面向对象性中的一种概念,只是它不是一种面向对象的一种方式了,它把其中的一些方法以及服务呢做成一种切面!它“你”去通过!在后面再详说~Spring,它也提供了ORM,学到现在已经对ORM不陌生了,关系对象模型,大家可能会首先想到Hibernate.,其实在Spring中它已经集成了Hibernate,因此我们需要将 Hibernate加入到Spring中来是非常方便的!我们可以将 其数据源直接配在我们的applicationcontext.xml中, 另外它也提供一个Spring Web服务,以及DAO,所谓的数据访问对象,还有就是Spring context对象,所谓的上下文对象,它里面提供了一个ApplicationContext,当然它自身也提供了MVC,而最终它底层依赖一个核心的库,是这样一种结构!
上图是它的整体结构,这里的容器使用的是Tomcat,它的UI层用的是Struts,它通过Spring的AOP以及ORM技术与后台进行交互!该图交互的可能是Hibernate!这样就体现出Stuts做UI层,而Spring做控制层,Hibernate做模型层。MVC!
Spring 中有一些术语,介绍如下:
轻量级:它的大小是比较小的,它的核心库才一百多K,它的整个框架体系加起来也才一MB左右,不是很大!
非入侵式:假如说一种框架你在应用的时候很依赖于这种框架,就是说你在开发的时候很多地方都依赖这种框架,很多地方你离开了这种框架就运行不了,像Struts,Struts有点像是入侵式的,像我们的JSP页,里面有很多<html:***>这样的一些标记!这些标记一旦离开了Struts框架体系运行 就不行了,那么什么是非入侵式的呢,就是一种组件,或框架,我们离开了它也能活!在这个框架里面也行,这种就叫做非入侵式的,也就是我们的程序与框架关联不是太紧密的!
容器:容器就相当于水缸,篮子,它可以存入组件!可以给主键提供一个运行环境!它可以帮助管理我们以前需要手工编写程序去管理对象关系的工作
IOC/DI:IOC就是我们上面提到的反转控制,或者称为DI依赖注入!它是Spring最核心的概念,使用Spring我们不必在程序中维护对象的依赖关系,只要在XML设定,Spring容器会自己根据相关配置去产生他们之间的关系,就相当于所有的关系都是在容器运行的时候注入的,而本身他们的关系是没有的!(Hibernate)也是这样的!好比有二个人上学,在他们上学前这二个人之间是没有任何关系的,而当他们被学校分配到一个班级的时候,它们就有了关系 ,同学!这个就相当于是反转控制,在由容器运行的时候通过XML来确定类与类之间的关系!
AOP:也是Spring被人重视的另一方面!其实AOP只是Spring支持的一个子容器,AOP(Aspect oriented programming)
我们可以在玩游戏的时候经常有这样情景,假如存在一个通道,其中有二个门,假设当我们的角色通过第一道门的时候,我们的红会加100,而再通过第二道门的时候我们的蓝会加100,现在提出一个问题,就是假如我们这个游戏里面该通道上没有这二个门,是正常的吗?当然是,也行!只不过人物角色不能在通过该通道的时候加红和蓝,并不影响游戏的整体!就是说有一些服务在我们的WEB应用程序中不是一些必须的服务,就像是Log4J,日志服务!假如说没有它,我们的程序也行,就是像这样的一些服务,它与我们的应用程序需求无关,但我们又提供了,那么程序中其实有时候有许多这样的情景,就是程序并不是必须,好比上面的门,我们看整个通道,那么这二个门是不是好比是二个切面呢?我们穿过一个门的时候是不是穿过一个空间的切面了!这种就叫做面向切面性,把一种技术做成一种切面的形式,你只要通过这个切面的形式,你就获得了这个服务,它其实是面向对象的一种补长,因为面向对象性它只能做为一个对象,我们就必须把一个对象完整的做出来,那么好比上面的游戏,有这样一个战士,我们做一个战士类,那么当它经过那二门的时候,我们如果以面向对象来考虑,那么 我们要在战士这个类中定义二扇门,一扇加红一扇加蓝,那么这样这二扇门就变成战士的二属性了,那如果这二扇门不存在了,那战士岂不……这应该是不行的!这样我们以切面性来做的话,就可以将战士二扇门属性去掉,然后做二个祝福门,只要战士经过这二门,就会得到红蓝!这其实就是一种AOP概念!
持久层:Spring它提供了对持久层的整合!
WEB框架整合:Spring也提供了WEB的MVC解决方案,可以很好的善用IOC和AOP的功能,我们可以轻松的替换掉VIEW层,如使用JSP,结合Tiles,使用PDF作为用户的使用界面,也可以使用熟悉的WEB容器如JSF和Struts技术与Spring整合!
好了,我们来写一种程序来看一下什么叫做依赖注入:我们建立一个JAVA Project(Spring不一定仅仅用在J2EE中,也一样可以应用在J2SE)
我们仅仅加载一个核心包就可以了,暂时没有用到AOP以及ORM,
这是产生一个配置文件,我们在J2EE中主要放在WEB-INF下。这里我们放在fengyan包下,单击完成,我们先建立一个简单的Bean,User.java.
package fengyan;
/** *//**
*
* @author: fengyan
* date: 2006-12-31 02:37
*
*/
public class User {
private String userName;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
我们再写一个主函数:TestMain.java
package fengyan;
/** *//**
*
* @author: fengyan
* date: 2006-12-31 02:39
*
*/
public class TestMain {
public static void main(String[] args){
//依赖注入
User user = new User();
user.setUserName("fengyan");
System.out.println(user.getUserName());
}
}
这样在运行的时候会输出:fengyan
但这种看一下,我们的User与TestMain 之间就有关系了,也就是如果我们要将fengyan改为efly那么我们就需要在TestMain类中修改,这样就形成了一种紧藕合,它们二个类边在一块了,那么 我们能不能有一种方法可以在二个类内部都不改动的情况下可以输出efly呢,肯定是可以的,那么我们现在在Myeclipse给我们生成的spring配置文件 applicationContext.xml中修改,我们先打开该文件,然后鼠标移至其内部空白地,右键,如下:
看到上图,就想到在Struts中,与我们在Struts的配置文件中操作相似,那个里面是也有new action form,等等!
我们设置bean ID为user 存放于我们建立的fengyan包下,然后选择properties属性,添加一个value属性userNane,变量名一定要对应类中,值就改为我们需要的efly,单击完成后看该文件代码如下:
<! DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >
< beans >
< bean id ="user" class ="fengyan.User" abstract ="false"
singleton ="true" lazy-init ="default" autowire ="default"
dependency-check ="default" >
< property name ="userName" >
< value > efly </ value >
</ property >
</ bean >
</ beans >
看起来有点像我们的jsp中的<jsp:usebean class="">。那么产生后我们如何去调用呢,回头改改TestMain
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
/** */ /**
*
* @author: fengyan
* date: 2006-12-31 02:39
*
*/
public class TestMain {
public static void main(String[] args){
/**//*
//依赖注入
User user = new User();
user.setUserName("fengyan");
System.out.println(user.getUserName());
*/
//ICO 反转控制
ApplicationContext context = new FileSystemXmlApplicationContext("fengyan/applicationContext.xml");
//这样我们获取了一个全局的应用程序上下文对象
//下面我们创建实例就不是先前的直接new 了
User user = (User)context.getBean("user");//是对象类型,需转换
System.out.println(user.getUserName());
}
}
这样efly就输出了,那么现在我们要再换为xuanfly就不需要动该二个类文件了,直接改配置文件,这就是IOC技术。