第1章Spring基础.docx

上传人:b****5 文档编号:3787194 上传时间:2022-11-25 格式:DOCX 页数:22 大小:275.33KB
下载 相关 举报
第1章Spring基础.docx_第1页
第1页 / 共22页
第1章Spring基础.docx_第2页
第2页 / 共22页
第1章Spring基础.docx_第3页
第3页 / 共22页
第1章Spring基础.docx_第4页
第4页 / 共22页
第1章Spring基础.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

第1章Spring基础.docx

《第1章Spring基础.docx》由会员分享,可在线阅读,更多相关《第1章Spring基础.docx(22页珍藏版)》请在冰豆网上搜索。

第1章Spring基础.docx

第1章Spring基础

第1章

Spring基础

 

本章目标

ØSpring概述

Ø相关的Java基础知识

ØIoC概述

本章能实现如下任务

Ø理解Spring基础概念

Ø理解Java反射机制

Ø理解IoC基础概念

 

本章简介

Spring具有很多功能,可以归纳为几个核心部件,Spring的主要特性是依赖注入(DI)和面向切面编程(AOP)。

本门课程主要讲解Spring的特性DI和AOP、Spring与ORM框架的集成、Spring与WEB框架的集成、Spring声明式事务等内容。

本章我们将会学习什么是IoC,如何实现IoC,在Eclipse中添加Spring支持等。

 

 

1.1Spring概述

1.1.1Spring基础

RodJohson在2002年编著的《ExpertonetooneJ2EEdesignanddevelopment》一书中,对JavaEE正统框架臃肿、低效、脱离现实的种种现状提出了质疑,并积极寻求探索革新之道。

以此书为指导思想,他编写了interface21框架,这是一个力图冲破JavaEE传统开发的困境,从实际需求出发,着眼于轻便、灵巧,易于开发、测试和部署的轻量级开发框架。

Spring框架即以interface21框架为基础,经过重新设计,并不断丰富其内涵,于2004年3月24日,发布了1.0正式版。

同年他又推出了一部堪称经典的力作《Expertone-to-oneJ2EEDevelopmentwithoutEJB》,该书在Java世界掀起了轩然大波,不断改变着Java开发者程序设计和开发的思考方式。

在该书中,作者根据自己多年丰富的实践经验,对EJB的各种笨重臃肿的结构进行了逐一的分析和否定,并分别以简洁实用的方式替换之。

至此一战功成,RodJohnson成为一个改变Java世界的大师级人物。

  

传统J2EE应用的开发效率低,应用服务器厂商对各种技术的支持并没有真正统一,导致J2EE的应用没有真正实现WriteOnce及RunAnywhere的承诺。

Spring作为开源的中间件,独立于各种应用服务器,甚至无须应用服务器的支持,也能提供应用服务器的功能,如声明式事务等。

  

Spring致力于J2EE应用的各层的解决方案,而不是仅仅专注于某一层的方案。

可以说Spring是企业应用开发的“一站式”选择,并贯穿表现层、业务层及持久层。

然而,Spring并不想取代那些已有的框架,而是与它们无缝地整合。

Spring具有很多功能,可以将它们归纳为几个基本部件,Spring是一个轻量级的DI和AOP容器框架。

也许这个描述并不简单,但它确实概括出了Spring的核心功能。

为了深入了解Spring,让我们把这个描述分解开来。

Ø轻量级——从大小和应用开支上说Spring都算是轻量级的。

整个Spring框架可以打成一个2.5MB多一点的JAR包,并且Spring的处理开支也非常小。

更重要的是,Spring是非侵入式的:

基于Spring开发的应用中的对象一般不依赖于Spring的类。

Ø依赖注入——Spring提供了一种松耦合的技术,称为依赖注入(DI)。

使用DI,对象是被动接收依赖类而不是自己主动去找。

你可以将DI理解为JNDI的反转——对象不是从容器中查找它的依赖类,而是容器在实例化对象的时候主动将它的依赖类注入给它。

Ø面向切面——Spring对面向切面编程提供了强大支持,通过将业务逻辑从应用服务(如监控和事务管理)中分离出来,实现了内聚开发。

应用对象只做它们该做的——业务逻辑,它们不负责(或关心)其系统问题(如日志和事务支持)。

Ø容器——Spring是一个容器,因为它包含并且管理应用对象的生命周期和配置。

你可以通过配置来设定你的Bean是单一实例,还是每次请求产生一个实例,并且设定它们之间的关联关系。

Spring有别于传统的重量级EJB容器,这些容器通常很大,很笨重。

Ø框架——Spring实现了使用简单的组件配置组合成一个复杂的应用。

在Spring中,应用中的对象是通过XML文件配置组合起来的。

并且Spring提供了很多基础功能(事务管理、持久层集成等),这使开发人员能够专注于开发应用逻辑。

总之,将Spring划分为这几个基本组件,所获得就是一个Spring框架,它能够帮助你开发出松耦合的应用代码,这些工作都是由Spring完成的,松耦合的优点(可维护性和可测试性)使得Spring更具有价值且应用范围更广。

1.1.2Spring框架构成

Spring框架是一个分层架构,由7个定义良好的模块组成。

Spring模块构建在核心容器之上,核心容器定义了创建、配置和管理bean的方式,如图1.1所示。

图1.1Spring框架结构

组成Spring框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。

每个模块的功能如下:

Ø核心容器:

核心容器提供Spring框架的基本功能。

核心容器的主要组件是BeanFactory,它是工厂模式的实现。

BeanFactory使用控制反转(IOC)模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。

ØSpring上下文:

Spring上下文是一个配置文件,向Spring框架提供上下文信息。

Spring上下文包括企业服务,例如JNDI、EJB、电子邮件、国际化、校验和调度功能。

ØSpringAOP:

通过配置管理特性,SpringAOP模块直接将面向方面的编程功能集成到了Spring框架中。

所以,可以很容易地使Spring框架管理的任何对象支持AOP。

SpringAOP模块为基于Spring的应用程序中的对象提供了事务管理服务。

通过使用SpringAOP,不用依赖EJB组件,就可以将声明性事务管理集成到应用程序中。

ØSpringDAO:

JDBCDAO抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。

异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。

SpringDAO的面向JDBC的异常遵从通用的DAO异常层次结构。

ØSpringORM:

Spring框架插入了若干个ORM框架,从而提供了ORM的对象关系工具,其中包括JDO、Hibernate和iBatisSQLMap。

所有这些都遵从Spring的通用事务和DAO异常层次结构。

ØSpringWeb模块:

Web上下文模块建立在应用程序上下文模块之上,为基于Web的应用程序提供了上下文。

所以,Spring框架支持与JakartaStruts的集成。

Web模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。

ØSpringMVC框架:

MVC框架是一个全功能的构建Web应用程序的MVC实现。

通过策略接口,MVC框架变成为高度可配置的,MVC容纳了大量视图技术,其中包括JSP、Velocity、Tiles、iText和POI。

Spring框架的功能可以用在任何J2EE服务器中,大多数功能也适用于不受管理的环境。

Spring的核心要点是:

支持不绑定到特定J2EE服务的可重用业务和数据访问对象。

毫无疑问,这样的对象可以在不同J2EE环境(Web或EJB)、独立应用程序、测试环境之间重用。

1.1.3Spring2.0的新特性

在Spring2.0发布附带的文档里面对2.0新特性做了概要的介绍,2.0的新特性是自然是我们最关注的方面:

一、Spring的XML配置引入XMLSchema语法简化配置

二、提供了request和session范围的bean

三、集成AspectJ,可以管理容器外对象,提供了领域模型的依赖注入

四、JPA支持

五、JDBC的NamedParameterJdbcTemplate

六、SpringWebMVC功能的大幅度扩充

七、支持动态语言ruby,groovy,beanshell

八、异步JMS支持,JMX支持,JCA支持的功能完善

因此Spring是一个野心很大的框架,从现在状况来看,Spring可以说是Java开源框架之集大成者,从未来来看,Spring将提供J2EE厂商所能够提供的所有必要的功能,最终Spring将有可能取J2EE规范而代之,成为Java企业开发的事实平台和事实标准。

总体来说,Spring2.0将向未来的宏大目标又迈进了一大步。

不过对于我等普通JavaWeb项目的开发需求来说,2.0的新特性也没有特别需要的。

1.2相关的Java基础知识

1.2.1类装载器ClassLoader

类装载器主是寻找类或接口字节码文件进行解析并构造JVM内部对象表示的组件。

在Java中,类装载器把一个类装入JVM中,要经过以下步骤:

1、装载:

查找和导入Class文件;

2、链接:

执行校验、准备和解析步骤,其中解析步骤是可以选择的;

校验:

检查载入Class文件数据的正确性;

准备:

给类的静态变量分配存储空间;

解析:

将符号引用转成直接引用;

3、初始化:

对类的静态变量、静态代码块执行初始化工作。

类装载工作由ClassLoader及其子类负责,ClassLoader是一个重要的Java运行时系统组件,它负责在运行时查找和装入Class字节文件。

1.2.2Java反射机制

Class反射对象描述语义结构,可以从Class对象中获取构造函数、成员变量、方法类等元素的反射对象,并以编程的方式通过这些反射对象对目标类对象进行操作。

这些反射对象类在java.reflect包中定义,下面最主要的三个反射类。

ØConstructor:

类的构造方法反射类,通过Class类getConstructors()方法可以获得类的所有构造方法反射对象数组。

Constructor的一个主要方法是newInstance(Object[]initargs),通过该方法可以创建一个对象类的实例,相当于new关键字。

ØMethod:

类方法的反射类,通过Class类getDeclaredMethods()方法可以获取类的所有方法反射类对象数组Method[]。

Method最主要的方法是invoke(Objectobj,Object[]args),obj表示操作的目标对象;args为方法入参。

此外,Method还有很多用于获取类方法更多信息的方法。

1)ClassgetReturnType():

获取方法的返回值类型;

2)Class[]getParameterTypes():

获取方法的入参类型数组;

3)Class[]getExceptionTypes():

获取方法的异常类型数组;

4)Annotation[][]getParameterAnnotations():

获取方法的注解信息。

ØField:

类的成员变量的反射类,通过Class类getDeclaredFields()方法可以获取类的成员变量的反射类,通过Class类getDeclaredFields(Stringname)方法刚可以获取某个特定名称的成员变量反射对象。

Fields类最主要的方法是set(Objectobj,Objectvalue),obj表示操作的目标对象,通过value为目标对象的成员变量设置值。

我们将从一个简单例子讲解Java反射机制,下面的Student类拥有两个构造方法、三个属性及多个常规方法。

具体代码如实例1所示:

实例1

packageorg.hopetech.reflect;

publicclassStudent{

privateStringname;

privateStringsex;

privateintage;

publicStudent(){

}

publicStudent(Stringname,Stringsex,intage){

this.name=name;

this.sex=sex;

this.age=age;

}

publicvoidintroduce(){

System.out.println("姓名:

"+name+"\n性别:

"+sex+"\n年龄:

"+age);

}

publicStringgetName(){

returnname;

}

publicvoidsetName(Stringname){

this.name=name;

}

publicStringgetSex(){

returnsex;

}

publicvoidsetSex(Stringsex){

this.sex=sex;

}

publicintgetAge(){

returnage;

}

publicvoidsetAge(intage){

this.age=age;

}

}

通常,我们会使用以下代码创建Student实例:

Studentstud=newStudent();

stud.setName(“张三”);

stud.setSex(“男”);

stud.setAge(22);

Studentstud=newStudent(“张三”,”男”,22);

上述两种方法都采用传统的直接调用目标类的方式进行操作,下面我们通过Java反射机制以一种更加通用的方式间接的操作目标类,具体代码如实例2所示:

实例2

packageorg.hopetech.reflect;

importjava.lang.reflect.Constructor;

importjava.lang.reflect.Method;

publicclassRelfectTest{

publicstaticStudentinitByDefaultConst()throwsThrowable{

ClassLoaderloader=Thread.currentThread().getContextClassLoader();

Classclazz=loader.loadClass("org.hopetech.reflect.Student");

Constructorcons=clazz.getConstructor((Class[])null);

Studentstud=(Student)cons.newInstance();

MethodsetName=clazz.getMethod("setName",String.class);

setName.invoke(stud,"张三");

MethodsetSex=clazz.getMethod("setSex",String.class);

setSex.invoke(stud,"男");

MethodsetAge=clazz.getMethod("setAge",int.class);

setAge.invoke(stud,22);

returnstud;

}

publicstaticvoidmain(String[]args)throwsThrowable{

Studentstud=initByDefaultConst();

stud.introduce();

}

}

实例2运行结果如图1.2所示:

图1.2实例2运行结果

1.3Java的反射和代理实现IOC模式

1.3.1关于IoC与DI的概念

首先想说说IoC(InversionofControl,控制倒转)。

这是spring的核心,贯穿始终。

所谓IoC,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系。

这是什么意思呢,举个简单的例子,我们是如何找女朋友的?

常见的情况是,我们到处去看哪里有长得漂亮身材又好的女孩,然后打听她们的兴趣爱好、qq号、电话号、ip号、iq号………,想办法认识她们,投其所好送其所要,这个过程是复杂深奥的,我们必须自己设计和面对每个环节。

传统的程序开发也是如此,在一个对象中,如果要使用另外的对象,就必须得到它(自己new一个,或者从JNDI中查询一个),使用完之后还要将对象销毁(比如Connection等),对象始终会和其他的接口或类藕合起来。

那么IoC是如何做的呢?

有点像通过婚介找女朋友,在我和女朋友之间引入了一个第三者:

婚姻介绍所。

婚介管理了很多男男女女的资料,我可以向婚介提出一个列表,告诉它我想找个什么样的女朋友,比如长得像李嘉欣,身材像林熙雷,唱歌像周杰伦,速度像卡洛斯,技术像齐达内之类的,然后婚介就会按照我们的要求,提供一个女孩,我们只需要去和她谈恋爱、结婚就行了。

简单明了,如果婚介给我们的人选不符合要求,我们就会抛出异常。

整个过程不再由我自己控制,而是有婚介这样一个类似容器的机构来控制。

Spring所倡导的开发方式就是如此,所有的类都会在spring容器中登记,告诉spring你是个什么东西,你需要什么东西,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。

所有的类的创建、销毁都由spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring。

对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转。

IoC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。

这一点是通过DI(DependencyInjection,依赖注入)来实现的。

比如对象A需要操作数据库,以前我们总是要在A中自己编写代码来获得一个Connection对象,有了spring我们就只需要告诉spring,A中需要一个Connection,至于这个Connection怎么构造,何时构造,A不需要知道。

在系统运行时,spring会在适当的时候制造一个Connection,然后像打针一样,注射到A当中,这样就完成了对各个对象之间关系的控制。

A需要依赖Connection才能正常运行,而这个Connection是由spring注入到A中的,依赖注入的名字就这么来的。

那么DI是如何实现的呢?

Java1.3之后一个重要特征是反射(reflection),它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。

1.3.2实现IoC

根据前面所举的例子,我用代码方式来解决找女朋友这个问题。

首先,我们必须设计一个Girl类,根据它可以构建多个不同类型的女孩来,具体的代码如实例3所示。

实例3

packageorg.hopetech.spring;

publicclassGirl{

privateStringname;//姓名

privateIntegerage;//年龄

privateBooleanbeautiful;//是否漂亮

publicGirl(){

}

publicIntegergetAge(){

returnage;

}

publicvoidsetAge(Integerage){

this.age=age;

}

publicBooleangetBeautiful(){

returnbeautiful;

}

publicvoidsetBeautiful(Booleanbeautiful){

this.beautiful=beautiful;

}

publicStringgetName(){

returnname;

}

publicvoidsetName(Stringname){

this.name=name;

}

}

然后,我们设计一个Boy类。

因为他需要约会,因此他依赖一个可以完成和他约会的女朋友。

当然,他也可以直接构建一个Girl对象,但这样一来,他的可选择性就只能是唯一的一个了。

因此,我们可以设定,他需要一个女朋友,而这个女朋友可以由婚介所来提供,这样他的可选择就大了很多。

具体代码如实例4所示。

实例4

packageorg.hopetech.spring;

publicclassBoy{

privateStringname;//姓名

privateGirlgirlFriend;//女朋友对象

publicBoy(){

}

publicvoidsetName(Stringname){

this.name=name;

}

/**

*注入女朋友

*

*@paramgirlFriend

*/

publicvoidsetGirlFriend(GirlgirlFriend){

this.girlFriend=girlFriend;

}

/**

*约会

*/

publicvoidmeetting(){

if(girlFriend.getAge()<20){

System.out.println("年龄没有20岁,"+name+"与"+girlFriend.getName()+"约会失败");

return;

}

if(!

girlFriend.getBeautiful()){

System.out.println("长的对不起观众"+name+"与"+girlFriend.getName()+"约会失败");

return;

}

System.out.println(name+"拉着"+girlFriend.getName()+"的手高兴的约会去了.");

}

}

婚介所拟定约会对象,制定了一个约会清单,具体的代码如实例5所示。

实例5

xmlversion="1.0"encoding="UTF-8"?

>

--凤姐的资料-->

--将凤姐设为曾哥的约会对象-->

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 英语

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1