最新动态
【Spring从入门到实战教程】第一章 Spring概述
2024-11-25 03:55  浏览:72

【Spring从入门到实战教程】第一章 Spring概述

    Spring 是一款目前主流的 Java EE 轻量级开源框架,是 Java 世界最为成功的框架之一。Spring 由“Spring 之父”Rod Johnson 提出并创立,其目的是用于简化 Java 企业级应用的开发难度和开发周期。          自 2004 年 4 月,Spring 1.0 版本正式发布以来,Spring 已经步入到了第 5 个大版本,也就是我们常说的 Spring 5。          Spring 自诞生以来备受青睐,一直被广大开发人员作为 Java 企业级应用程序开发的首选。时至今日,Spring 俨然成为了 Java EE 代名词,成为了构建 Java EE 应用的事实标准。          Spring 框架不局限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何 Java 应用都可以从 Spring 中受益。Spring 框架还是一个超级粘合平台,除了自己提供功能外,还提供粘合其他技术和框架的能力。          Spring是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器框架。

具体描述 Spring

    轻量:从大小与开销两方面而言Spring都是轻量的。完整的Spring框架可以在一个大小只有1MB多的JAR文件里发布。并且Spring所需的处理开销也是微不足道的。此外,Spring是非侵入式的:典型地,Spring应用中的对象不依赖于Spring的特定类。我们之前学习的Servlet就是侵入性的,因为一个Java类想要成为Servlet,必须实现或继承Servlet API,但是Spring基本上不会。          核心思想:         控制反转:IOC(inversion of control)。         依赖注入:DI(dependency injection)。         面向切面编程:AOP(aspect oriented programming)。          容器:Spring包含并管理应用对象的配置和生命周期,在这个意义上它是一种容器,你可以配置你的每个bean如何被创建——基于一个可配置原型(prototype,你的bean可以创建一个单独的实例或者每次需要时都生成一个新的实例——以及它们是如何相互关联的。          框架:Spring可以将简单的组件配置、组合成为复杂的应用。在Spring中,应用对象被声明式地组合,典型地是在一个XML文件里。Spring也提供了很多基础功能(事务管理、持久化框架集成等等,将应用逻辑的开发留给了你。          一站式:在IOC和AOP的基础上可以整合各种企业应用的开源框架和优秀的第三方类库(例如:Struts2和Hibernate框架之间的协同工作,Spring在程序中是一个桥梁或者管理者,整个应用程序的运行都依靠Spring。实际上Spring自身也提供了展现层的SpringMVC和持久层的SpringJDBC。

1.1.1 Spring 的诞生与发展

    早期的 J2EE(Java EE 平台)推崇以 EJB 为核心的开发方式,但这种开发方式在实际的开发过程中存在种种弊端,例如使用复杂、代码臃肿、代码侵入性强、开发周期长、移植难度大等。

    Rod Johnson 在其 2002 年编著的畅销书《Expert One-on-One J2EE Design and Development》中,针对 EJB 各种臃肿的结构进行了逐一的分析和否定,并分别以更加简洁的方式进行了替换。

    在这本书中,Rod Johnson 通过一个包含 3 万行代码的附件,展示了如何在不使用 EJB 的情况下构建一个高质量、可扩展的 Java 应用程序。在这个附件中,Rod Johnson 编写了上万行基础结构代码,其中包含了许多可重用的 Java 接口和类,例如 ApplicationContext、BeanFactory 等。这些类的根包被命名为 com.interface21,含义为:这是提供给 21 世纪的一个参考。

    这本书影响甚远,后来 Rod Johnson 将 com.interface21 的代码开源,并把这个新框架并命名为“Spring”,含义为:Spring 像一缕春风一样,扫平传统 J2EE 的寒冬。

    2003 年 2 月,Spring 0.9 版本发布,它采用了 Apache 2.0 开源协议;2004 年 4 月,Spring 1.0 版本正式发布。到目前为止,Spring 已经步入到了第 5 个大版本,也就是我们常说的 Spring 5。

1.1.2 Spring 的狭义和广义

    在不同的语境中,Spring 所代表的含义是不同的。下面我们就分别从“广义”和“狭义”两个角度,对 Spring 进行介绍。          官网:https://spring.io/

广义的 Spring:Spring 技术栈

    广义上的 Spring 泛指以 Spring framework 为核心的 Spring 技术栈。

    经过十多年的发展,Spring 已经不再是一个单纯的应用框架,而是逐渐发展成为一个由多个不同子项目(模块)组成的成熟技术,例如 Spring framework、Spring MVC、SpringBoot、Spring Cloud、Spring Data、Spring Security 等,其中 Spring framework 是其他子项目的基础。

    这些子项目涵盖了从企业级应用开发到云计算等各方面的内容,能够帮助开发人员解决软件发展过程中不断产生的各种实际问题,给开发人员带来了更好的开发体验。

项目名称描述Spring DataSpring 提供的数据访问模块,对 JDBC 和 ORM 提供了很好的支持。通过它,开发人员可以使用一种相对统一的方式,来访问位于不同类型数据库中的数据。Spring Batch一款专门针对企业级系统中的日常批处理任务的轻量级框架,能够帮助开发人员方便的开发出健壮、高效的批处理应用程序。Spring Security前身为 Acegi,是 Spring 中较成熟的子模块之一。它是一款可以定制化的身份验证和访问控制框架。Spring Mobile是对 Spring MVC 的扩展,用来简化移动端 Web 应用的开发。Spring Boot是 Spring 团队提供的全新框架,它为 Spring 以及第三方库一些开箱即用的配置,可以简化 Spring 应用的搭建及开发过程。Spring Cloud一款基于 Spring Boot 实现的微服务框架。它并不是某一门技术,而是一系列微服务解决方案或框架的有序集合。它将市面上成熟的、经过验证的微服务框架整合起来,并通过 Spring Boot 的思想进行再封装,屏蔽调其中复杂的配置和实现原理,最终为开发人员提供了一套简单易懂、易部署和易维护的分布式系统开发工具包。

狭义的 Spring:Spring framework

    狭义的 Spring 特指 Spring framework,通常我们将它称为 Spring 框架。

    Spring 框架是一个分层的、面向切面的 Java 应用程序的一站式轻量级解决方案,它是 Spring 技术栈的核心和基础,是为了解决企业级应用开发的复杂性而创建的。

    Spring 有两个核心部分: IoC 和 AOP。

核心描述IOCInverse of Control 的简写,译为“控制反转”,指把创建对象过程交给 Spring 进行管理。AOPAspect Oriented Programming 的简写,译为“面向切面编程”。 AOP 用来封装多个类的公共行为,将那些与业务无关,却为业务模块所共同调用的逻辑封装起来,减少系统的重复代码,降低模块间的耦合度。另外,AOP 还解决一些系统层面上的问题,比如日志、事务、权限等。

    Spring 是一种基于 Bean 的编程技术,它深刻地改变着 Java 开发世界。Spring 使用简单、基本的 Java Bean 来完成以前只有 EJB 才能完成的工作,使得很多复杂的代码变得优雅和简洁,避免了 EJB 臃肿、低效的开发模式,极大的方便项目的后期维护、升级和扩展。

    在实际开发中,服务器端应用程序通常采用三层体系架构,分别为表现层(web)、业务逻辑层(service)、持久层(dao)。

    Spring 致力于 Java EE 应用各层的解决方案,对每一层都提供了技术支持。     在表现层提供了对 Spring MVC、Struts2 等框架的整合;     在业务逻辑层提供了管理事务和记录日志的功能;     在持久层还可以整合 MyBatis、Hibernate 和 JdbcTemplate 等技术,对数据库进行访问。

    这充分地体现了 Spring 是一个全面的解决方案,对于那些已经有较好解决方案的领域,Spring 绝不做重复的事情。

    从设计上看,Spring 框架给予了 Java 程序员更高的自由度,对业界的常见问题也提供了良好的解决方案,因此在开源社区受到了广泛的欢迎,并且被大部分公司作为 Java 项目开发的首选框架。

1.1.3 Spring framework 的特点

    Spring 框架具有以下几个特点。

    方便解耦,简化开发:Spring 就是一个大工厂,可以将所有对象的创建和依赖关系的维护交给 Spring 管理。

    方便集成各种优秀框架:Spring 不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如 Struts2、Hibernate、MyBatis 等)的直接支持。

    降低 Java EE API 的使用难度:Spring 对 Java EE 开发中非常难用的一些 API(JDBC、JavaMail、远程调用等)都提供了封装,使这些 API 应用的难度大大降低。

    方便程序的测试:Spring 支持 JUnit4,可以通过注解方便地测试 Spring 程序。

    AOP 编程的支持:Spring 提供面向切面编程,可以方便地实现对程序进行权限拦截和运行监控等功能。

    声明式事务的支持:只需要通过配置就可以完成对事务的管理,而无须手动编程。

    Spring 框架是一个分层架构,每个模块既可单独存在,又可与其他模块联合实现,其架构如下图所示

     Spring Core:Core模块是Spring的核心类库,Spring的所有功能都依赖于该类库,Core主要实现IOC功能,Sprign的所有功能都是借助IOC实现的。          Spring AOP:AOP模块是Spring的AOP库,为Spring容器管理的对象提供了对面向切面编程的支持。          Spring DAO:Spring 提供对JDBC的支持,对JDBC进行封装,允许JDBC使用Spring资源,同时还基于AOP模块提供了事务管理。          Spring ORM:Spring 的ORM模块提供对常用的ORM框架的管理和辅助支持,Spring支持常用的Hibernate,ibtas,jdo等框架的支持,Spring本身并不对ORM进行实现,仅对常见的ORM框架进行封装,并对其进行管理。          Spring Context:Context模块提供框架式的Bean访问方式,其他程序可以通过Context访问Spring的Bean资源。增加了对国际化、事件传播,以及验证等的支持,此外还提供了许多企业服务及对模版框架集成的支持。          Spring Web:WEB模块是建立于Context模块之上,提供了一个适合于Web应用的上下文。另外,也提供了Spring和其它Web框架(如Struts1、Struts2、JSF)的集成。          Spring Web MVC:WEB MVC模块为Spring提供了一套轻量级的MVC实现,是一个全功能的 Web 应用程序,容纳了大量视图技术,如 JSP、Velocity、POI等。

    IoC 是 Inversion of Control 的简写,译为“控制反转”,它不是一门技术,而是一种设计思想,是一个重要的面向对象编程法则,能够指导我们如何设计出松耦合、更优良的程序。

    Spring 通过 IoC 容器来管理所有 Java 对象的实例化和初始化,控制对象与对象之间的依赖关系。我们将由 IoC 容器管理的 Java 对象称为 Spring Bean,它与使用关键字 new 创建的 Java 对象没有任何区别。

    IoC 容器是 Spring 框架中最重要的核心组件之一,它贯穿了 Spring 从诞生到成长的整个过程。

1.3.1 通俗理解

Address类

 

Person类

 

测试

 

1.3.2 控制反转

    在传统的 Java 应用中,一个类想要调用另一个类中的属性或方法,通常会先在其代码中通过 new Object() 的方式将后者的对象创建出来,然后才能实现属性或方法的调用。为了方便理解和描述,我们可以将前者称为“调用者”,将后者称为“被调用者”。也就是说,调用者掌握着被调用者对象创建的控制权。

    但在 Spring 应用中,Java 对象创建的控制权是掌握在 IOC 容器手里的,其大致步骤如下。         1、开发人员通过 XML 配置文件、注解、Java 配置类等方式,对 Java 对象进行定义,例如在 XML 配置文件中使用 <bean> 标签、在 Java 类上使用 @Component 注解等。                  2、Spring 启动时,IoC 容器会自动根据对象定义,将这些对象创建并管理起来。这些被 IOC 容器创建并管理的对象被称为 Spring Bean。                  3、当我们想要使用某个 Bean 时,可以直接从 IOC 容器中获取(例如通过 ApplicationContext 的 getBean() 方法,而不需要手动通过代码(例如 new Obejct() 的方式)创建。

    IoC 带来的最大改变不是代码层面的,而是从思想层面上发生了“主从换位”的改变。原本调用者是主动的一方,它想要使用什么资源就会主动出击,自己创建;但在 Spring 应用中,IOC 容器掌握着主动权,调用者则变成了被动的一方,被动的等待 IOC 容器创建它所需要的对象(Bean)。

    这个过程在职责层面发生了控制权的反转,把原本调用者通过代码实现的对象的创建,反转给 IOC 容器来帮忙实现,因此我们将这个过程称为 Spring 的“控制反转”。

1.3.3 依赖注入

    在了解了 IoC 之后,我们还需要了解另外一个非常重要的概念:依赖注入。

    依赖注入(Denpendency Injection,简写为 DI)是 Martin Fowler 在 2004 年在对“控制反转”进行解释时提出的。Martin Fowler 认为“控制反转”一词很晦涩,无法让人很直接的理解“到底是哪里反转了”,因此他建议使用“依赖注入”来代替“控制反转”。

    在面向对象中,对象和对象之间是存在一种叫做“依赖”的关系。简单来说,依赖关系就是在一个对象中需要用到另外一个对象,即对象中存在一个属性,该属性是另外一个类的对象。

例如,有一个名为 B 的 Java 类,它的代码如下

 

    从代码可以看出,B 中存在一个 A 类型的对象属性 a,此时我们就可以说 B 的对象依赖于对象 a。而依赖注入就是就是基于这种“依赖关系”而产生的。

    我们知道,控制反转核心思想就是由 Spring 负责对象的创建。在对象创建过程中,Spring 会自动根据依赖关系,将它依赖的对象注入到当前对象中,这就是所谓的“依赖注入”。

1.3.4 IOC 的工作原理

    在 Java 软件开发过程中,系统中的各个对象之间、各个模块之间、软件系统和硬件系统之间,或多或少都存在一定的耦合关系。

    若一个系统的耦合度过高,那么就会造成难以维护的问题,但完全没有耦合的代码几乎无法完成任何工作,这是由于几乎所有的功能都需要代码之间相互协作、相互依赖才能完成。因此我们在程序设计时,所秉承的思想一般都是在不影响系统功能的前提下,最大限度的降低耦合度。

    IoC 底层通过工厂模式、Java 的反射机制、XML 解析等技术,将代码的耦合度降低到最低限度,其主要步骤如下。         1、在配置文件(例如 Bean.xml)中,对各个对象以及它们之间的依赖关系进行配置;                  2、我们可以把 IoC 容器当做一个工厂,这个工厂的产品就是 Spring Bean;                  3、容器启动时会加载并解析这些配置文件,得到对象的基本信息以及它们之间的依赖关系;                  4、IoC 利用 Java 的反射机制,根据类名生成相应的对象(即 Spring Bean,并根据依赖关系将这个对象注入到依赖它的对象中。

    由于对象的基本信息、对象之间的依赖关系都是在配置文件中定义的,并没有在代码中紧密耦合,因此即使对象发生改变,我们也只需要在配置文件中进行修改即可,而无须对 Java 代码进行修改,这就是 Spring IoC 实现解耦的原理。

1.4.1 创建一个Java项目

    在Spring的基础模块中,没有和Web相关内容,无需创建JavaWEB项目,建立Java项目即可。

1.4.2 导入核心的jar包

Spring 框架的核心包

名称作用spring-core-x.x.xx.jar包含 Spring 框架基本的核心工具类,Spring 其他组件都要用到这个包中的类,是其他组件的基本核心。spring-beans-x.x.xx.jar所有应用都要用到的,它包含访问配置文件、创建和管理 Bean 以及进行 Inversion of Control(IoC)或者 Dependency Injection(DI)操作相关的所有类。spring-context-x.x.xx.jarSpring 提供在基础 IoC 功能上的扩展服务,此外还提供许多企业级服务的支持,如邮件服务、任务调度、JNDI 定位、EJB 集成、远程访问、缓存以及各种视图层框架的封装等。spring-expression-x.x.xx.jar定义了 Spring 的表达式语言。 需要注意的是,在使用 Spring 开发时,除了 Spring 自带的 JAR 包以外,还需要一个第三方 JAR 包 commons.logging 处理日志信息。

方式一:引入jar包

 方式二:maven依赖配置

 

1.4.3 编写Bean

HelloWorld.java

 

1.4.4 编写Spring配置文件

    applicationContext.xml为默认名称,作用是在SpringIOC容器中配置需要让Spring来管理的Bean对象。          Spring的配置管理可以利用XML方式进行配置,而XML里面就有命名空间这个概念。实际上就和标签的意思有点像,你给一个命名空间以后,这个XML文件里面就可以用那个命名空间上下文里面的标签了。          1、beans:xml文件的根节点。          2、xmlns:是XML NameSpace的缩写,因为XML文件的标签名称都是自定义的,自己写的和其他人定义的标签很有可能会重复命名,而功能却不一样,所以需要加上一个namespace来区分这个xml文件和其他的xml文件,类似于java中的package。          3、xmlns:xsi:是指xml文件遵守xml规范,xsi全名:xml schema instance,是指具体用到的schema资源文件里定义的元素所准守的规范。即http://www.w3.org/2001/XMLSchema-instance这个文件里定义的元素遵守什么标准。          4、xsi:schemaLocation:是指本文档里的xml元素所遵守的规范,这些规范都是由官方制定的,可以进你写的网址里面看版本的变动。xsd的网址还可以帮助你判断使用的代码是否合法。

 

Schema和DTD的区别

    Schema是对XML文档结构的定义和描述,其主要的作用是用来约束XML文件,并验证XML文件有效性。DTD的作用是定义XML的合法构建模块,它使用一系列的合法元素来定义文档结构。它们之间的区别有下面几点

    1、Schema本身也是XML文档,DTD定义跟XML没有什么关系,Schema在理解和实际应用有很多的好处。

    2、DTD文档的结构是“平铺型”的,如果定义复杂的XML文档,很难把握各元素之间的嵌套关系;Schema文档结构性强,各元素之间的嵌套关系非常直观。

    3、DTD只能指定元素含有文本,不能定义元素文本的具体类型,如字符型、整型、日期型、自定义类型等。Schema在这方面比DTD强大。

    4、Schema支持元素节点顺序的描述,DTD没有提供无序情况的描述,要定义无序必需穷举排列的所有情况。Schema可以利用xs:all来表示无序的情况。

    5、对命名空间的支持。DTD无法利用XML的命名空间,Schema很好满足命名空间。并且,Schema还提供了include和import两种引用命名空间的方法。

    6、XML Schema不能像DTD一样定义实体,比DTD更复杂,但Xml Schema现在已是w3c组织的标准,它正逐步取代DTD。

Schema好处

    1、XML用户在使用XML Schema的时候,不需要为了理解XML Schema而重新学习,节省了时间;          2、由于XML Schema本身也是一种XML,所以许多的XML编辑工具、API 开发包、XML语法分析器可以直接的应用到XML Schema,而不需要修改。          3、作为XML的一个应用,XML Schema理所当然的继承了XML的自描述性和可扩展性,这使得XML Schema 更具有可读性和灵活性。          4、由于格式完全与XML一样,XML Schema除了可以像XML一样处理外,也可以同它所描述的XML文档以同样的方式存储在一起,方便管理。          5、XML Schema与XML格式的一致性,使得以XML为数据交换的应用系统之间,也可以方便的进行模式交换。          6、XML有非常高的合法性要求,XML DTD对XML的描述,往往也被用作验证XML合法性的一个基础,但是XML DTD本身的合法性却缺少较好的验证机制,必需独立处理。XML Schema则不同,它与XML有着同样的合法性验证机制。

1.4.5 测试

 

关于以上代码,需要注意以下两点