【Spring学习】Spring之旅

1.Spring之旅

1.1 简化Java开发

1.1.1 Spring介绍

Spring可以做很多事情,为企业级开发提供给了丰富的功能,这些功能的底层都依赖于他的两个核心特性,也就是依赖注入(DI,dependency injection)和面向切面编程(AOP,aspect-oriented programming)。

在诞生之初,创建Spring的主要目的是用来替代更加重量级的企业级Java技术,尤其是EJB。相对于EJB来说,Spring提供了更加轻量级和简单的编程模型。它增强了简单老式Java对象(Plain Old Java object,POJO)的功能,使其具备了之前只有EJB和其他企业级Java规范才具有的功能。

Spring是为了解决企业级应用开发的复杂性而创建的,使用Spring可以让简单的JavaBean实现之前只有EJB才能完成的事情。但Spring不仅仅局限于服务器端开发,任何Java应用都能在简单性、可测试性和松耦合等方面从Spring中获益。

Spring的目标:致力于全方位的简化Java开发。这势必会引出更多的解释,Spring是如何简化Java开发的?

为了降低Java开发的复杂性,Spring采取了以下4个关键策略:

1)基于POJO的轻量级和最小侵入性编程

2)通过依赖注入和面向接口实现松耦合

3)基于切面和惯例进行声明式编程

4)通过切面和模板减少样板式代码

package com.habuma.spring;

public class HelloWorldBean {

public String sayHello(){

return "Hello World";

}

}

这是一个简答普通的Java类——POJO,没有任何地方表明它是一个Spring组件。Spring的非侵入编程模型意味着这个类在Spring应用和非Spring应用中都可以发挥同样的作用。尽管形式看起来简单,但是POJO一样可以具有魔力。Spring赋予POJO魔力的方式之一就是通过DI来装配它们。

耦合具有两面性(two-headed beast)。一方面,紧密耦合的代码难以测试、难以复用、难以理解,并且典型地表现出“打地鼠”式的bug特性(修复一个bug,将会出现一个或者更多新的bug)。另一方面,一定程度的耦合又是必须的——完全没有耦合的代码什么也做不了。为了完成有实际意义的功能,不同的类必须以适当的方式进行交互。总而言之,耦合是必须的,但应当被小心谨慎地管理。

1.1.2 依赖注入

通过DI,对象的依赖关系将由系统中负责协调各对象的第三方组件在创建对象的时候进行设定。对象无需自行创建或管理它们的依赖关系。如下图,依赖关系将被自动注入到需要它们的对象当中。

【Spring学习】Spring之旅_第1张图片

依赖注入的方式之一:构造器注入(即构造的时候作为构造器参数传入)。

创建应用组件之间协作的行为通常称为装配(wiring)。Sping有多种装配bean的方式,采用XML是很常见的一种方式。

Spring通过应用上下文(Application Context)装载bean的定义并把它们组装起来。Spring应用上下文全权负责对象的创建和组装。Spring自带了多种应用上下文的实现,它们之间主要的区别仅仅在于如何加载配置。

1.1.3 应用切面

面向切面编程(aspect-oriented programming,AOP)允许你把遍布应用各处的功能分离出来形成可重用的组件

面向切面编程往往被定义为促使软件系统实现关注点的分离一项技术。系统由许多不同的组件组成,每一个组件各负责一块特定功能。除了实现自身核心的功能之外,这些组件还经常承担着额外的职责。诸如日志、事务管理和安全这样的系统服务经常融入到自身具有核心业务逻辑的组件中去,这些系统服务通常被称为横切关注点,因为它们会跨越系统的多个组件。

如果将这些关注点分散到多个组件中去,你的代码将会带来双重的复杂性。

【Spring学习】Spring之旅_第2张图片

AOP能够使这些服务模块化,并以声明的方式将它们应用到它们需要影响的组件中去。所造成的结果就是这些组件会具有更高的内聚性并更加关注自身的业务,完全不需要了解涉及系统服务所带来复杂性。总之,AOP能够确保POJO的简单性

Spring的aop配置命令, 前置通知,后置通知

1.1.4 使用模板消除样板式代码

你是否写过这样的代码,当编写的时候总会感觉以前曾经这么写过?我的朋友,这不是似曾相识。这是样板式的代码(boilerplate code)。

遗憾的是,它们中的很多是因为使用Java API而导致的样板式代码。样板式代码的一个常见范例是使用JDBC访问数据库查询数据。JDBC不是产生样板式代码的唯一场景。在许多编程场景中往往都会导致类似的样板式代码,JMS、JNDI使用REST服务通常也涉及大量的重复代码。

Spring旨在通过模板封装来消除样板式代码。Spring的JdbcTemplate使得执行数据库操作时,避免传统的JDBC样板代码成为了可能。

1.2 容纳你的Bean

Spring容器,这是应用中的所有bean所驻留的地方。

在基于Spring的应用中,你的应用对象生存于Spring容器(container)中。Spring容器负责创建对象,装配它们,配置它们并管理它们的整个生命周期,从生存到死亡(在这里,可能就是new到finalize())。如下图:

【Spring学习】Spring之旅_第3张图片

容器是Spring框架的核心。Spring容器使用DI管理构成应用的组件,它会创建相互协作的组件之间的关联。毫无疑问,这些对象更简单干净,更易于理解,更易于重用并且更易于进行单元测试。

Spring容器并不是只有一个。Spring自带了多个容器实现,可以归为两种不同的类型bean工厂(由org.springframework. beans.factory.eanFactory接口定义)是最简单的容器,提供基本的DI支持应用上下文(由org.springframework.context.ApplicationContext接口定义)基于BeanFactory构建,并提供应用框架级别的服务,例如从属性文件解析文本信息以及发布应用事件给感兴趣的事件监听者。

1.2.1 使用应用上下文

Spring自带了多种类型的应用上下文。下面罗列的几个是你最有可能遇到的。

1)AnnotationConfigApplicationContext:从一个或多个基于Java的配置类中加载Spring应用上下文。

2)AnnotationConfigWebApplicationContext:从一个或多个基于Java的配置类中加载Spring Web应用上下文。

3)ClassPathXmlApplicationContext:从类路径下的一个或多个XML配置文件中加载上下文定义,把应用上下文的定义文件作为类资源

4)FileSystemXmlapplicationcontext:从文件系统下的一个或多个XML配置文件中加载上下文定义。

5)XmlWebApplicationContext:从Web应用下的一个或多个XML配置文件中加载上下文定义。

应用上下文准备就绪之后,我们就可以调用上下文的getBean()方法从Spring容器中获取bean

1.2.2 bean的生命周期

下图展示了bean装载到Spring应用上下文中的一个典型的生命周期过程。

【Spring学习】Spring之旅_第4张图片

在bean准备就绪之前,bean工厂执行了若干启动步骤。

我们对图1.5进行详细描述:

1.Spring对bean进行实例化;

2.Spring将值和bean的引用注入到bean对应的属性中;

3.如果bean实现了BeanNameAware接口,Spring将bean的ID传递给setBean-Name()方法;

4.如果bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入;

5.如果bean实现了ApplicationContextAware接口,Spring将调用setApplicationContext()方法,将bean所在的应用上下文的引用传入进来;

6.如果bean实现了BeanPostProcessor接口,Spring将调用它们的post-ProcessBeforeInitialization()方法;

7.如果bean实现了InitializingBean接口,Spring将调用它们的after-PropertiesSet()方法。类似地,如果bean使用init-method声明了初始化方法,该方法也会被调用;

8.如果bean实现了BeanPostProcessor接口,Spring将调用它们的post-ProcessAfterInitialization()方法;

9.此时,bean已经准备就绪,可以被应用程序使用了,它们将一直驻留在应用上下文中,直到该应用上下文被销毁;

10.如果bean实现了DisposableBean接口,Spring将调用它的destroy()接口方法。同样,如果bean使用destroy-method声明了销毁方法,该方法也会被调用。

1.3 俯瞰Spring风景线

在Spring框架的范畴内,你会发现Spring简化Java开发的多种方式。但在Spring框架之外还存在一个构建在核心框架之上的庞大生态圈,它将Spring扩展到不同的领域,例如Web服务、REST、移动开发以及NoSQL。

1.3.1 Spring模块

当我们下载Spring发布版本并查看其lib目录时,会发现里面有多个JAR文件。

在Spring 4.0中,Spring框架的发布版本包括了20个不同的模块,每个模块会有3个JAR文件(二进制类库、源码的JAR文件以及JavaDoc的JAR文件)。

这些模块依据其所属的功能可以划分为6类不同的功能。如下图:

【Spring学习】Spring之旅_第5张图片

Spring核心容器

容器是Spring框架最核心的部分,它管理着Spring应用中bean的创建、配置和管理。在该模块中,包括了Spring bean工厂,它为Spring提供了DI的功能。基于bean工厂,我们还会发现有多种Spring应用上下文的实现,每一种都提供了配置Spring的不同方式。

除了bean工厂和应用上下文,该模块也提供了许多企业服务,例如E-mail、JNDI访问、EJB集成和调度。

所有的Spring模块都构建于核心容器之上。当你配置应用时,其实你隐式地使用了这些类。

Spring的AOP模块

在AOP模块中,Spring对面向切面编程提供了丰富的支持。这个模块是Spring应用系统中开发切面的基础。与DI一样,AOP可以帮助应用对象解耦。借助于AOP,可以将遍布系统的关注点(例如事务和安全)从它们所应用的对象中解耦出来。

数据访问与集成

Spring的JDBC和DAO(Data Access Object)模块抽象了这些样板式代码,使我们的数据库代码变得简单明了,还可以避免因为关闭数据库资源失败而引发的问题。

Spring提供了ORM模块。Spring的ORM模块建立在对DAO的支持之上,并为多个ORM框架提供了一种构建DAO的简便方式。Spring没有尝试去创建自己的ORM解决方案,而是对许多流行的ORM框架进行了集成,包括Hibernate、Java Persisternce API、Java Data Object和iBATIS SQL Maps。Spring的事务管理支持所有的ORM框架以及JDBC。

Web与远程调用

MVC(Model-View-Controller)模式是一种普遍被接受的构建Web应用的方法,它可以帮助用户将界面逻辑与应用逻辑分离。Java从来不缺少MVC框架,Apache的Struts、JSF、WebWork和Tapestry都是可选的最流行的MVC框架。

虽然Spring能够与多种流行的MVC框架进行集成,但它的Web和远程调用模块自带了一个强大的MVC框架,有助于在Web层提升应用的松耦合水平。

除了面向用户的Web应用,该模块还提供了多种构建与其他应用交互的远程调用方案。Spring远程调用功能集成了RMI(Remote Method Invocation)、Hessian、Burlap、JAX-WS,同时Spring还自带了一个远程调用框架:HTTP invoker。Spring还提供了暴露和使用REST API的良好支持。

Instrumentation

Spring的Instrumentation模块提供了为JVM添加代理(agent)的功能。具体来讲,它为Tomcat提供了一个织入代理,能够为Tomcat传递类文件,就像这些文件是被类加载器加载的一样。

测试

鉴于开发者自测的重要性,Spring提供了测试模块以致力于Spring应用的测试。

通过该模块,你会发现Spring为使用JNDI、Servlet和Portlet编写单元测试提供了一系列的mock对象实现。对于集成测试,该模块为加载Spring应用上下文中的bean集合以及与Spring上下文中的bean进行交互提供了支持。

1.3.2 Spring Portfolio

事实上,Spring远不是Spring框架所下载的那些。如果仅仅停留在核心的Spring框架层

面,我们将错过Spring Portfolio所提供的巨额财富。整个Spring Portfolio包括多个构建于核心Spring框架之上的框架和类库。概括地讲,整个Spring Portfolio几乎为每一个领域的Java开发都提供Spring

编程模型。

Spring Web Flow

Spring Web Flow建立于Spring MVC框架之上,它为基于流程的会话式Web应用(可以想一下购物车或者向导功能)提供了支持。你还可以访问Spring Web Flow的主页(http://projects.spring.io/spring-webflow/)。

Spring Web Service

虽然核心的Spring框架提供了将Spring bean以声明的方式发布为WebService的功能,但是这些服务是基于一个具有争议性的架构(拙劣的契约后置模型)之上而构建的。这些服务的契约由bean的接口来决定。 Spring Web Service提供了契约优先的Web Service模型,服务的实现都是为了满足服务的契约而编写的。本书不会再探讨Spring Web Service,但是你可以浏览站点http://docs.spring.io/spring- ws/site/来了解更多关于Spring Web Service

的信息。

Spring Security

安全对于许多应用都是一个非常关键的切面。利用Spring AOP,Spring Security为Spring应用提供了声明式的安全机制。你可以在主页http://projects.spring.io/spring-security/上获得关于Spring Security的更多信息。

Spring Integration

许多企业级应用都需要与其他应用进行交互。Spring Integration提供了多种通用应用集成模式的Spring声明式风格实现。如果你想了解更多关于Spring Integration的信息,推荐Mark Fisher、Jonas Partner、Marius Bogoevici和Iwein Fuld编写的《Spring Integration in Action》(Manning,2012,www.manning.com/fisher/);或者你还可以访问Spring Integration的主页http://projects.spring.io/spring-integration/。

Spring Batch

当我们需要对数据进行大量操作时,没有任何技术可以比批处理更胜任这种场景。如果需要开发一个批处理应用,你可以通过SpringBatch,使用Spring强大的面向POJO的编程模型。你可以阅读Arnaud Cogoluegnes、Thierry Templier、Gary Gregory和Olivier Bazoud编写的《Spring Batch in Action》(Manning,2012,www.manning.com/templier/),或者访问Spring Batch的主页http://projects.spring.io/ spring-batch/。

Spring Data

Spring Data使得在Spring中使用任何数据库都变得非常容易。尽管关系型数据库统治企业级应用多年,但是现代化的应用正在认识到并不是所有的数据都适合放在一张表中的行和列中。一种新的数据库种类,通常被称之为NoSQL数据库 ,提供了使用数据的新方法,这些

方法会比传统的关系型数据库更为合适。

不管你使用文档数据库,如MongoDB,图数据库,如Neo4j,还是传统的关系型数据库,Spring Data都为持久化提供了一种简单的编程模型。这包括为多种数据库类型提供了一种自动化的Repository机制,它负责为你创建Repository的实现。

Spring Social

社交网络是互联网领域中新兴的一种潮流,越来越多的应用正在融入社交网络网站,例如Facebook或者Twitter。如果对此感兴趣,你可以了解一下Spring Social,这是Spring的一个社交网络扩展模块。不过,Spring Social并不仅仅是tweet和好友。尽管名字是这样,但Spring Social更多的是关注连接(connect),而不是社交(social)。它能够帮助你通过REST API连接Spring应用,其中有些Spring应用可能原本并没有任何社交方面的功能目标。如果你对Spring如何帮助你连接Facebook或Twitter感兴趣的话,可以查看网址https://spring.io/guides/gs/accessing- facebook/和

https://spring.io/guides/gs/accessing-twitter/中的入门指南。

Spring Mobile

移动应用是另一个引人瞩目的软件开发领域。智能手机和平板设备已成为许多用户首选的客户端。Spring Mobile是Spring MVC新的扩展模块,用于支持移动Web应用开发。

Spring for Android

与Spring Mobile相关的是Spring Android项目。这个新项目,旨在通过Spring框架为开发基于Android设备的本地应用提供某些简单的支持。最初,这个项目提供了Spring RestTemplate的一个可以用于

Android应用之中的版本。它还能与Spring Social协作,使得原生应用可以通过REST API进行社交网络的连接。你可以通过http://projects.spring.io /spring-android/了解更多内容。

Spring Boot

Spring极大地简化了众多的编程任务,减少甚至消除了很多样板式代码,如果没有Spring的话,在日常工作中你不得不编写这样的样板代码。Spring Boot是一个崭新的令人兴奋的项目,它以Spring的视角,致力于简化Spring本身。

Spring Boot大量依赖于自动配置技术,它能够消除大部分(在很多场景中,甚至是全部)Spring配置。它还提供了多个Starter项目,不管你使用Maven还是Gradle,这都能减少Spring工程构建文件的大小。

 

摘自《Spring实战》第四版。

更新于2018-7-21

                                                                                                                                                                

你可能感兴趣的:(Spring)