vlambda博客
学习文章列表

读书笔记《hands-on-high-performance-with-spring-5》探寻春天的概念

Exploring Spring Concepts

Spring 框架 为管理大型企业 Java 应用程序提供了广泛的支持,还解决了企业应用程序开发的复杂性。 Spring 为现代企业应用程序提供了一套完整的 API 和配置模型,使程序员只需要专注于应用程序的业务逻辑。

作为轻量级框架引入的 Spring 框架旨在提供一种方法,使 Java 企业应用程序的开发变得简单易行。

本章将帮助您更好地理解 Spring Framework 的核心特性。我们将从介绍 Spring 框架开始。本章还将让您清楚地了解 Spring Framework 的每个主要模块。在快速浏览了 Spring 框架中的重要模块之后,我们将深入 Spring 项目的世界。我们也会对Spring Inversion of ControlIoCcontainer有一个清晰的认识跨度>。最后,我们将看看 Spring 5.0 中引入的新特性和增强功能。

在本章中,我们将研究以下主题:

  • Introducing the Spring Framework
  • Understanding Spring modules
  • Spring projects
  • Spring IoC container
  • New features in Spring Framework 5.0

Introducing the Spring Framework

Spring 框架是最流行的开源 Java 应用程序框架和 IoC 容器之一。 Spring 最初是由 Rod Johnson 和 Jurgen Holler 开发的。 Spring Framework 的第一个里程碑版本于 2004 年 3 月发布。尽管已经过去了 15 年,但 Spring Framework 仍然是构建任何 Java 应用程序的首选框架。

Spring Framework 为开发企业 Java 应用程序提供了全面的基础架构支持。因此,开发人员无需担心应用程序的基础架构;他们可以专注于应用程序的业务逻辑,而不是处理应用程序的配置。

所有基于 Java 或基于 XML 的基础设施、配置和元配置文件都由 Spring Framework 处理。因此,这个框架让您在使用 Plain Old Java Object (POJO) 编程模型而不是非侵入式编程模型构建应用程序时更加灵活。

Spring IoC 容器通过将任何应用程序的各种组件组合在一起构成了整个框架的核心。 Spring Model-View-Controller (MVC) 组件可用于构建非常灵活的 Web 层。 IoC 容器使用 POJO 简化了业务层的开发。

Problems with EJB

在早期,程序员很难管理企业应用程序,因为像 Enterprise JavaBeans (EJB) 这样的企业 Java 技术在提供企业解决方案方面要重得多。程序员。

当 EJB 技术首次发布时,它提供了一种分布式组件模型,允许开发人员只关注系统的业务端,而忽略中间件需求,例如组件的连接、事务管理、持久性操作、安全性、资源池化、线程化、分发、远程处理等;但是,对于 EJB 应用程序的开发、单元测试和部署来说,这是一个非常繁琐的过程。使用 EJB 时面临以下一些复杂性:

  • Forcing implementation of unnecessary interfaces and methods
  • Making unit testing difficult, especially outside the EJB container
  • Inconveniences in managing deployment descriptors
  • Tedious exception handling

当时,Spring 被引入作为专门为 EJB 设计的替代技术,因为与其他现有的 Java 技术相比,Spring 提供了一种非常简单、更精简、更轻量级的编程模型。 Spring 使得克服上述复杂性成为可能,并且通过使用许多可用的设计模式来避免使用其他一些较重的企业技术。 Spring Framework 专注于 POJO 编程模型,而不是非侵入式编程模型。该模型为 Spring Framework 提供了简单性。它还赋予了诸如依赖注入(DI)模式和面向方面编程(AOP)等思想,使用代理模式和装饰器模式。

Simplifying implementation using POJO

POJO 编程模型最重要的优点是编码应用程序类非常快速和简单。这是因为类不需要依赖任何特定的 API、实现任何特殊的接口或从特定的框架类扩展。在您真正需要它们之前,您不必创建任何特殊的回调方法。

Benefits of the Spring Framework

Spring 框架的重要好处如下:

  • No need to reinvent the wheel
  • Ease of unit testing
  • Reduction in implementing code
  • Inversion of control and API
  • Consistency in transaction management
  • Modular architecture
  • Up to date with time

让我们详细讨论一下。

No need to reinvent the wheel

无需重新发明轮子是开发人员可以从 Spring 框架中利用的最重要的好处之一。它促进了众所周知的技术、ORM 框架、日志框架、JEE、JDK 计时器、Quartz 等的实际使用。因此,开发人员不必学习任何新技术或框架。

它促进了良好的编程实践,例如使用接口而不是类进行编程。 Spring 使开发人员能够使用 POJO 和 Plain Old Java Interface (POJI) 模型编程来开发企业应用程序。

Ease of unit testing

如果你想测试使用 Spring 开发的应用程序,这很容易。这背后的主要原因是该框架中提供了与环境相关的代码。 早期版本的 EJB 很难进行单元测试。甚至很难在容器外运行 EJB (从 2.1 版开始)。测试它们的唯一方法是将它们部署在 容器中。

Spring 框架引入了 DI 概念。我们将在 第 2 章Spring 最佳实践中详细讨论 DI和 Bean 布线配置。 DI 支持单元测试。这是通过用他们的模拟替换依赖关系来完成的。整个应用程序不需要部署到单元测试。

单元测试有很多好处:

  • Improving the productivity of programmers
  • Detecting defects at earlier stages, thereby saving the cost of fixing them
  • Preventing future defects by automating unit tests in applications that are running in continuous integration (CI) builds

Reduction in implementing code

所有应用类都是简单的POJO类;春天不是侵入性的。它不需要您为大多数用例扩展框架类或实现框架接口。 Spring 应用程序不需要 Jakarta EE 应用程序服务器,但它们可以部署在一个服务器上。

在 Spring Framework 之前,典型的 J2EE 应用程序包含大量管道代码。例如:

  • Code for getting a database connection
  • Code for handling exceptions
  • Transaction management code
  • Logging code and a lot more

让我们看一下使用 PreparedStatement 执行查询的以下简单示例:

PreparedStatement st = null;
try {
    st = conn.prepareStatement(INSERT_ACCOUNT_QUERY);
    st.setString(1, bean.getAccountName());
    st.setInt(2, bean.getAccountNumber());
    st.execute();
}
catch (SQLException e) {
    logger.error("Failed : " + INSERT_ACCOUNT_QUERY, e);
} finally {
    if (st != null) {
        try {
            st.close();
        } catch (SQLException e) {
            logger.log(Level.SEVERE, INSERT_ACCOUNT_QUERY, e);
        }
    }
}

在前面的示例中,有 4 行业务逻辑和 10 多行管道代码。使用 Spring Framework 可以在几行中应用相同的逻辑,如下所示:

jdbcTemplate.update(INSERT_ACCOUNT_QUERY,
bean.getAccountName(), bean.getAccountNumber());

使用 Spring,您可以将 Java 方法用作请求处理程序方法或远程方法,如 servlet API 的 service() 方法,但无需处理 servlet 容器的 servlet API。它支持基于 XML 和基于注释的配置。

Spring 使您能够使用本地 Java 方法作为消息处理程序方法,而无需在应用程序中使用 Java 消息服务 (JMS) API。 Spring 充当应用程序对象的容器。您的对象不必担心寻找和建立彼此的连接。 Spring 还允许您将本地 Java 方法用作管理操作,而无需在应用程序中使用 Java 管理扩展 (JMX) API。

Inversion of control and API

Spring 还帮助开发人员摆脱了编写单独的编译单元或单独的类加载器来处理异常的必要性。 Spring 转换依赖于技术的异常,尤其是由 Java Database Connectivity (JDBC)、Hibernate 或 Java Data Objects (JDO strong>),进入未经检查且一致的异常。 Spring 使用控制反转和 API 来实现这一点。

此外,它使用 IoC 进行 DI,这意味着可以正常配置方面。如果我们想添加我们自己的行为,我们需要扩展框架的类或插入我们自己的类。以下是这种架构的优点列表:

  • Decoupling the execution of a task from its implementation
  • Making it easier to switch between different implementations
  • Greater modularity of a program
  • Greater ease in testing a program by isolating a component or mocking it
  • Dependencies and allowing components to communicate through contracts

Consistency in transaction management

Spring 还提供了对事务管理的一致性支持。它提供了一种简单灵活的方式来配置小型应用程序的本地事务以及使用 Java Transaction API (JTA) 的大型应用程序的全局事务。所以我们不需要使用任何第三方事务API来执行数据库事务; Spring 将使用事务管理功能来处理它。

Modular architecture

Spring 提供了一种模块化架构,可以帮助开发人员识别要使用和忽略的包或类。因此,通过这种方式,我们可以只保留那些我们真正需要的东西。因此,即使有很多包或类,也可以轻松识别和利用可用的包或类。

Spring 是一个强大的框架,它解决了 Jakarta EE 中的许多常见问题。它包括对管理业务对象和将其服务公开给表示层组件的支持。

Spring 实例化 bean 并将对象的依赖项注入到应用程序中,它充当 bean 的生命周期管理器。

Up to date with time

在构建 Spring Framework 的第一个版本时,它的主要重点是使应用程序可测试。在后来的版本中也有新的挑战,但 Spring 框架设法发展并保持领先,并与所提供的架构灵活性和模块保持一致。一些例子列举如下:

  • The Spring Framework introduced a number of abstractions ahead of Jakarta EE to keep the application decoupled from the specific implementation
  • The Spring Framework also provided transparent caching support in Spring 3.1
  • Jakarta EE was introduced with JSR-107 for JCache in 2014, so it was provided in Spring 4.1

Spring 参与的另一个主要演变是提供不同的 Spring 项目。 Spring 框架只是 Spring 项目中的众多项目之一。以下示例说明了 Spring 框架如何在 Spring 项目方面保持最新:

  • As architecture evolved toward cloud and microservices, Spring came up with new cloud-oriented Spring projects. The Spring Cloud project simplifies development and deployment of microservices.
  • To build Java batch applications, a new approach was introduced as the Spring Batch project by the Spring Framework.

在下一节中,我们将深入探讨不同的 Spring Framework 模块。

Understanding Spring modules

Spring 提供了模块化架构,这是 Spring Framework 流行的最重要原因之一。其分层架构可以轻松轻松地集成其他框架。这些模块提供了开发人员在企业应用程序开发中可能需要使用的一切。 Spring 框架被组织成 20 个不同的模块,这些模块构建在其核心容器之上。

下面的 diagram 展示了以分层架构组织的不同 Spring 模块:

读书笔记《hands-on-high-performance-with-spring-5》探寻春天的概念
Spring Framework modules

在继续讨论其他模块之前,我们将从讨论核心容器开始。

Core Container

Spring核心容器提供了Spring框架的核心特性,即Core、Beans、Context和Expression Language,具体如下:

Artifact

模块使用

弹簧芯

该模块促进了其他模块使用的所有实用程序,它还提供了一种管理不同 bean 生命周期操作的方法。

弹簧豆

该模块主要用于解耦代码依赖与你的实际业务逻辑,并消除使用DI和IoC特性的单例类的使用。

弹簧上下文

该模块提供国际化和资源加载等功能,还支持 EJB、JMS 和远程处理等 Java EE 功能。

弹簧表达式

该模块支持在运行时访问 bean 的属性,并允许我们操作它们。

Crosscutting concerns

横切关注点适用于应用程序的所有层,包括日志记录和安全性等。与横切关注点相关的重要 Spring 模块如下:

Artifact Module Usage

spring-aop

该模块主要用于执行系统不同部分中常见的任务,如事务管理、日志记录和安全性。为了实现这一点,我们可以实现方法拦截器和切入点。

弹簧方面

该模块用于集成任何自定义对象类型。可以使用AspectJ,这个模块的主要用途是整合不受容器控制的对象。

弹簧仪器

This module is used to measure the application's performance and also helps to perform error diagnosis using trace information.

弹簧测试

该模块用于在 Spring 应用程序中集成测试支持。

Data Access/Integration

应用程序中的数据访问/集成层与数据库和/或外部接口交互。它由 JDBC、ORM、OXM、JMS 和 Transaction 模块组成。这些模块是 spring-jdbcspring-ormspring-oxmspring-jmsspring-tx

Web

Web 层包含 Web、Web-MVC、Web-Socket 和其他 Web-Portlet 模块。各自的模块名称是spring-webspring-webmvcspring-websocketspring-webmvc-portlet .

在下一节中,我们将介绍不同类型的 Spring 项目。

Spring projects

Spring Framework 为不同的基础设施需求提供了不同类型的项目,也有助于探索企业应用程序中其他问题的解决方案:部署、云、大数据和安全等。

下面列出了一些重要的 Spring 项目:

  • Spring Boot
  • Spring Data
  • Spring Batch
  • Spring Cloud
  • Spring Security
  • Spring HATEOAS

让我们详细讨论它们。

Spring Boot

Spring Boot 支持创建可以运行的独立、生产级、基于 Spring 的应用程序。

Spring Boot 还提供了以下一些开箱即用的功能,通过对应用程序开发方式的固执看法:

  • Provides support for developing standalone Spring applications
  • Embeds Tomcat, Jetty, or Undertow directly, with no need to deploy WAR files
  • Allow us to externalize configuration to work in different environments with the same application code
  • Simplifies Maven configuration by providing opinionated starter POMs
  • Eliminates the need for code generation and the requirement for XML configuration
  • Provides support for production features like metrics, health checks, and application monitoring

我们将在 第 12 章中深入了解 Spring Boot,Spring Boot微服务性能调优

Spring Data

Spring Data 项目的主要目标是提供一个简单且一致的基于 Spring 的模型来访问数据和其他特殊功能,以操作基于 SQL 和 NoSQL 的数据存储。它还试图提供一种使用数据访问技术、map-reduce 框架、关系和非关系数据库以及基于云的数据服务的简单方法。

一些重要特征如下:

  • Provides support for integration with custom repository code
  • Provides repository and object-mapping abstractions by deriving dynamic queries using repository method names
  • Advanced integration support with Spring MVC controllers
  • Advanced support for transparent auditing features such as created by, created date, last changed by, and last changed date
  • Experimental integration support for cross-store persistence

Spring Data 为以下数据源提供集成支持:

  • JPA
  • JDBC
  • LDAP
  • MongoDB
  • Gemfire
  • REST
  • Redis
  • Apache Cassandra
  • Apache Solr

Spring Batch

Spring Batch 通过提供可重用的功能,促进对大量记录的基本处理,包括日志记录/跟踪、事务管理、作业处理统计、作业重启、跳过和资源管理.它还提供了更先进的技术服务和功能,可以使用优化和分区技术实现超大容量和高性能的批处理作业。

Spring Batch 的重要特性如下:

  • The ability to process data in chunks
  • The ability to start, stop and restart jobs, including the ability to restart, in the case of failed jobs, from the point where they failed
  • The ability to retry steps or to skip steps on failure
  • Web-based administration interface

Spring Cloud

毫不夸张地说世界正在向云迁移

Spring Cloud 为开发人员提供了在分布式系统中构建通用模式的工具。 Spring Cloud 使开发人员能够快速构建实现通用模式的服务和应用程序,以在任何分布式环境中工作。

Spring Cloud 中实现的一些常见模式如下:

  • Distributed configuration
  • Service registration and discovery
  • Circuit breakers
  • Load balancing
  • Intelligent routing
  • Distributed messaging
  • Global locks

Spring Security

身份验证和授权是企业应用程序(Web 应用程序和 Web 服务)的重要组成部分。 Spring Security 是一个功能强大且高度可定制的身份验证和访问控制框架。 Spring Security 专注于为 Java 应用程序提供声明式身份验证和授权。

Spring Security 中的重要特性如下:

  • Comprehensive support for both authentication and authorization
  • Good support for integration with servlet APIs and Spring MVC
  • Module support for integration with Security Assertion Markup Language (SAML) and Lightweight Directory Access Protocol (LDAP)
  • Providing support for common security attacks such as Cross-Site Forgery Request (CSRF), session fixation, clickjacking, and so on

我们将在 第 4 章中讨论如何使用 Spring Security 保护 Web 应用程序,Spring MVC 优化

Spring HATEOAS

Hypermedia As The Engine Of Application State (HATEOAS) 的主要目的是将服务器(服务提供者)与客户端(服务消费者)。服务器向客户端提供有关可以对资源执行的其他可能操作的信息。

Spring HATEOAS 提供了 HATEOAS 实现,特别是对于使用 Spring MVC 实现的 REpresentational State Transfer (REST) 服务。

Spring HATEOAS 具有以下重要特性:

  • A simplified definition of links pointing to service methods, making the links less fragile
  • Support for JSON and JAXB (XML-based) integration
  • Support for hypermedia formats such as Hypertext Application Language (HAL)

在下一节中,我们将了解 Spring 的 IoC 容器的机制。

Spring's IoC container

Spring 的 IoC 容器 被构建为 Spring 架构的核心模块。 IoC 也称为 DI。它是一种设计模式,它消除了代码的依赖性,从而简化了管理和测试应用程序。在 DI 中,对象本身通过构造函数参数、工厂方法的参数或对象实例在创建或从工厂方法返回后设置的属性来描述它们与它们工作的其他对象的依赖关系。

然后容器负责在创建 bean 时注入这些依赖项。这个过程基本上是 bean 本身通过使用类的直接构造或机制来控制其依赖项的实例化或位置的逆过程(因此称为 IoC)。

Spring Framework 的 IoC 容器有两个主要的基础包:org.springframework.beansorg.springframework.contextBeanFactory 接口提供了一些高级配置机制来管理任何类型的对象。 ApplicationContext 包含了BeanFactory 的所有功能,并充当它的子接口。事实上,ApplicationContext 也比 BeanFactory 更值得推荐,它提供了更多的支持基础设施,可以: 更容易地与 Spring 的 AOP 特性和事务集成;在国际化和事件发布方面的消息资源处理;和应用层特定的上下文,例如 WebApplicationContext 用于 Web 应用程序。

接口 org.springframework.context.ApplicationContext 表示为 Spring IoC 容器,它完全控制 bean 的生命周期并负责实例化、配置和组装 bean。

容器通过扫描 bean 配置元数据获取实例化、配置和组装的所有指令。可以使用以下方法表示配置元数据:

  • XML-based configuration
  • Annotation-based configuration
  • Java-based configuration

我们将在第 2 章Spring 最佳实践和 Bean 布线配置

下图代表了Spring Container创建完全配置的应用程序的过程:

读书笔记《hands-on-high-performance-with-spring-5》探寻春天的概念
The Spring IoC container

以下示例显示了基于 XML 的配置元数据的基本结构:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

 <!-- All the bean configuration goes here -->
<bean id="..." class="...">

</bean>

<!-- more bean definitions go here -->

</beans>

id 属性是一个字符串,用于标识单个 bean 定义。 class 属性定义bean 的类型,并使用完全限定的class 名称。 id 属性的值是指协作对象。

What are Spring beans?

您可以将 Spring bean 视为一个简单的 Java 对象,由 Spring IoC 容器实例化、配置和管理。它被称为 bean 而不是对象或组件,因为它相对于框架的起源而言是复杂和繁重的企业 JavaBeans 的替代品。我们将在 第 2 章中了解更多关于 Spring bean 实例化的方法,Spring最佳实践和 Bean 布线配置

Instantiating a Spring container

为了创建 bean 实例,我们首先需要通过读取配置元数据来实例化一个 Spring IoC 容器。初始化 IoC 容器后,我们可以使用 bean 名称或 ID 获取 bean 实例。

Spring 提供了两种类型的 IoC 容器实现:

  • BeanFactory
  • ApplicationContext

BeanFactory

BeanFactory 容器是为 DI 提供基本支持的最简单的容器,它由 org.springframework.beans.factory.BeanFactory 接口定义。 BeanFactory 负责获取、配置和组装对象之间的依赖关系。 BeanFactory 主要充当对象池,通过配置管理对象的创建和销毁。 BeanFactory 最流行和最有用的实现是 org.springframework.context.support.ClassPathXmlApplicationContextClassPathXmlApplicationContext 使用 XML 配置元数据来创建完全配置的应用程序。

以下示例使用 ClassPathXmlApplicationContext 定义了一个简单的 HelloWorld 应用程序。 Beans.xml 的内容如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

  <bean id="bankAccount" class="com.packt.springhighperformance.ch1.bankingapp.BankAccount">
    <property name="accountType" value="Savings Bank Account" />
  </bean>
</beans>

上述 XML 代码表示 bean XML 配置的内容。它配置了一个 bean,它有一个带有 name 消息的属性。它为属性设置了默认的 value

现在,下面的 Java 类代表前面 XML 中配置的 bean

让我们看一下HelloWorld.java

package com.packt.springhighperformance.ch1.bankingapp;

public class BankAccount {
  private String accountType;

  public void setAccountType(String accountType) {
    this.accountType = accountType;
  }

  public String getAccountType() {
    return this.accountType;
  }
}

最后,我们需要使用 ClassPathXmlApplicationContext 创建 HelloWorld bean 并调用创建的 Spring bean 中的方法。

Main.java 如下所示:

package com.packt.springhighperformance.ch1.bankingapp;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.
support.ClassPathXmlApplicationContext;

public class Main {

  private static final Logger LOGGER = Logger.getLogger(Main.class);

  @SuppressWarnings("resource")
  public static void main(String[] args) {
    BeanFactory beanFactory = new 
    ClassPathXmlApplicationContext("Beans.xml");
    BankAccount obj = (BankAccount) beanFactory.getBean("bankAccount");
    LOGGER.info(obj.getAccountType());
  }
}

ApplicationContext

ApplicationContext 容器支持使用 BeanFactory 方法访问应用程序组件。 包含BeanFactory的所有功能。此外,ApplicationContext 还可以执行更多的企业功能,例如事务、AOP、从属性文件解析文本消息以及将应用程序事件推送给感兴趣的侦听器。它还能够将事件发布到已注册的侦听器。

ApplicationContext 最常用的实现是 FileSystemXmlApplicationContextClassPathXmlApplicationContextAnnotationConfigApplicationContext

Spring 还为我们提供了 ApplicationContext 接口的 Web 感知实现,如下所示:

  • XmlWebApplicationContext
  • AnnotationConfigWebApplicationContext

我们可以使用这些实现中的任何一种来将 bean 加载到 BeanFactory 中;这取决于我们的应用程序配置文件位置。例如,如果我们想从特定位置的文件系统加载配置文件 Beans.xml,我们可以使用 FileSystemXmlApplicationContext 类来查找配置文件 Beans.xml 在文件系统中的特定位置:

ApplicationContext context = new
FileSystemXmlApplicationContext("E:/Spring/Beans.xml");

如果我们想从应用程序的类路径中加载我们的配置文件Beans.xml,我们可以使用Spring提供的ClassPathXmlApplicationContext类。此类在类路径中的任何位置查找配置文件 Beans.xml,包括 JAR 文件:

ApplicationContext context = new
ClassPathXmlApplicationContext("Beans.xml");

如果您使用的是 Java 配置而不是 XML 配置,则可以使用 AnnotationConfigApplicationContext

ApplicationContext context = new
AnnotationConfigApplicationContext(AppConfig.class);

在加载配置文件并获取到一个ApplicationContext之后,我们可以通过调用ApplicationContextgetBean()方法从Spring容器中获取bean:

BankAccountService bankAccountService =
context.getBean(BankAccountService.class);

在下一节中,我们将了解 Spring bean 的生命周期,以及 Spring 容器如何响应 Spring bean 来创建和管理它。

Spring bean life cycle

Spring ApplicationContext 使用工厂方法设计模式按照给定的配置以正确的顺序在容器中创建 Spring bean。因此,Spring 容器负责管理 bean 的生命周期,从创建到销毁。在普通的 Java 应用程序中,使用 Java 的 new 关键字来实例化 bean,并且可以使用它。一旦不再使用 bean,它就有资格进行垃圾收集。但是在 Spring 容器中,bean 的生命周期更加精细。

下图说明了典型 Spring bean 的生命周期:

读书笔记《hands-on-high-performance-with-spring-5》探寻春天的概念
Spring bean life cycle

在下一节中,我们将看到 Spring Framework 5.0 的新特性。

New features in the Spring Framework 5.0

Spring Framework 5.0 是 Spring Framework 的第一次重大升级,比 Spring Framework 4.0 晚近四年。在这个时间范围内,主要的发展之一是 Spring Boot 项目的演变。我们将在下一节讨论 Spring Boot 2.0 中的新特性。 Spring Framework 5.0 的最大特点之一是反应式编程。

Spring Framework 5.0 提供开箱即用的核心反应式编程功能和对反应式端点的支持。重要更改列表包括以下内容:

  • Baseline upgrades
  • Reactive programming support
  • Core features upgrades
  • Spring Web MVC upgrades
  • Spring's new functional web framework, WebFlux
  • Modularity support
  • Kotlin language support
  • Improved testing support
  • Dropped or deprecated features

我们将在以下部分详细讨论这些变化。

Baseline upgrades

整个 Spring Framework 5.0 具有 JDK 8 和 Jakarta EE 7 基线。基本上,这意味着要在 Spring Framework 5.0 上工作,Java 8 是最低要求。

Spring Framework 5.0 的一些重要基线 Jakarta EE 7 规范如下:

  • The code base of the Spring Framework 5.0 is based on Java 8 source code level now. So, the code readability is improved using inferred generics, lambdas, and so on. It also has the stability in the code for conditional support for Java 8 features.
  • The Spring Framework requires at least Jakarta EE 7 API level to run any of the Spring Framework 5.0 applications. It requires Servlet 3.1, Bean Validation 1.1, JPA 2.1, and JMS 2.0.
  • The development and deployment process is fully compatible with JDK 9 as follows:
    • Compatible with classpath and module path, with stable automatic module names
    • The Spring Framework's build and test suite also pass on JDK 9, and by default, it can be run on JDK 8

Reactive programming support

反应式编程模型在 Spring 5.0 最令人兴奋的特性中脱颖而出。 Spring 5.0 框架基于响应式基础,并且是完全异步和非阻塞的。新的事件循环执行模型可以使用 几个线程 垂直扩展。

该框架采购反应式流以提供一个系统,用于在反应式组件的管道中传送背压。背压是一种保证消费者不会被来自不同生产者的数据压倒的想法。

虽然 Java 8 没有内置对反应式编程的支持,但有许多框架提供对反应式编程的支持:

  • Reactive Streams: Language-neutral attempt to define reactive APIs
  • Reactor: Java implementation of Reactive Streams provided by the Spring Pivotal team
  • Spring WebFlux: Enables the development of web applications based on reactive programming; provides a programming model similar to Spring MVC

Core features upgrades

作为 Java 8 中引入的新特性的一部分,Spring Framework 5.0 的核心进行了修订,以提供以下一些关键特性:

  • Java 8 reflection enhancements include a provision of accessing method parameters in the Spring Framework 5.0 efficiently.
  • Provision of selective declaration support of Java 8 default methods in Spring Core interfaces.
  • Supports @Nullable and @NotNull annotations to explicitly mark nullable arguments and return values. This eliminates the cause of NullPointerExceptions at runtime and enables us to deal with null values at compile time.

对于日志记录方面,Spring Framework 5.0 通过 Commons Logging Bridge 模块提供了开箱即用的支持,名为 spring-jcl 而不是标准的Commons记录。此外,这个新版本将能够检测 Log4j 2.x、Simple Logging Facade for Java (SLF4J)、JUL(简称java.util.logging),没有任何额外的修改。

它还支持 Resource 通过提供< kbd>isFile 指标theme-classic-inline crayon-font-monaco">getFile 方法。

Spring Web MVC upgrades

Spring 5.0 完全支持 Spring 提供的 Filter 实现中的 Servlet 3.1 签名。它还支持 Spring MVC 控制器方法中的 Servlet 4.0 PushBuilder 参数。

Spring 5.0 还通过 MediaTypeFactory 委托提供对常见媒体类型的统一支持,包括使用 Java Activation Framework。

新的 ParsingPathMatcher 将作为 AntPathMatcher 的替代品,具有更高效的解析和扩展语法。

Spring 5.0 还将提供对 ResponseStatusException 的支持,作为 @ResponseStatus 的编程替代方案。

Spring's new functional web framework – WebFlux

另一个支持响应式 HTTP 和 WebSocket 客户端的令人兴奋的特性是 Spring Framework 5.0 提供了 spring-webflux 模块。 Spring Framework 5.0 还为在服务器上运行的响应式 Web 应用程序提供了对 REST、HTML 和 WebSocket 样式交互的支持。

spring-webflux服务端主要有两种编程模型:

  • Support for @Controller annotation including other Spring MVC annotations
  • Provision for functional style routing and handling with Java 8 Lambda

Spring spring-webflux 还提供了对创建 WebClient 的支持,它是响应式且非阻塞的,作为替代到 RestTemplate

Modularity support

模块化框架是 Java 平台上的趋势。从 Java 9 开始,Java 平台变得模块化,这有助于消除封装中的缺陷。

具有模块化支持会导致某些问题,如下所述:

  • Java platform size: Since the last couple of decades, there was no need to add modularity support in Java. But there are many new lightweight platforms available on the market, like the Internet of Things (IoT), and Node.js. So, it was an urgent need to reduce the size of JDK version, because initial versions of JDK were less than 10 MB in size, whereas recent versions need more than 200 MB.
  • ClassLoader difficulty: When the Java ClassLoader searches for the classes, it will pick the class definition that is around itself, and immediately load the first class available. So, if there is the same class available in different JARs, then it is not possible for ClassLoader to specify the JAR from which the class is to be loaded.

为了使 Java 应用程序模块化,开放系统网关倡议 (OSGi) 是将模块化引入 Java 平台的倡议之一。在 OSGi 中,每个模块都表示为 bundle。每个捆绑软件都有自己的生命周期,具有不同的安装、启动和停止状态。

Jigsaw 项目是 Java Community Process (JCP) 的主要动机,将模块化引入 Java。 其主要目的是为JDK定义和实现模块化结构,为Java应用程序定义一个模块系统。

Kotlin language support

Spring Framework 5.0 引入了静态类型的 JVM 语言,支持 Kotlin language (https://kotlinlang.org/),这使得代码变得简短、可读和富有表现力。 Kotlin 基本上是一种面向对象的语言,运行在 JVM 之上,也支持函数式编程风格。

借助 Kotlin 支持,我们可以深入研究函数式 Spring 编程,尤其是函数式 Web 端点和 bean 注册。

在 Spring Framework 5.0 中,我们可以为 Web 功能 API 编写干净易读的 Kotlin 代码,如下所示:

{
    ("/bank" and accept(TEXT_HTML)).nest {
        GET("/", bankHandler::findAllView)
        GET("/{customer}", bankHandler::findOneView)
    }
    ("/api/account" and accept(APPLICATION_JSON)).nest {
        GET("/", accountApiHandler::findAll)
        GET("/{id}", accountApiHandler::findOne)
    }
}

在 Spring 5.0 版本中,Kotlin 的 null-safety 支持还通过使用 @NonNull@Nullable@NonNullApi@NonNullFields 来自 org.springframework.lang 包。

有一些新添加的 Kotlin 扩展,基本上是在现有 Spring API 中添加功能扩展。例如,扩展 fun <T : Any> BeanFactory.getBean(): T 来自包 org.springframework.beans.factory org.springframework.beans 中添加支持.factory.BeanFactory 仅通过将 bean 类型指定为 Kotlin 的具体类型参数而不使用类参数来搜索 bean:

@Autowired
lateinit var beanFactory : BeanFactory

@PostConstruct
fun init() {
 val bankRepository = beanFactory.getBean<BankRepository>()

}

另一个扩展可以在 org.springframework.ui 中找到,它提供了操作符重载支持以向 model 接口添加类似数组的 getter 和 setter:

model["customerType"] = "Premium"

Improved testing support

在测试方面,Spring Framework 5.0 同样伴随着 JUnit Jupiter (https://junit. org/junit5/docs/current/user-guide/)。它有助于在 JUnit 5 中编写测试和扩展。它还提供了一个测试引擎来运行 Jupiter 构建的关于 Spring 的测试,还提供了一个编程和扩展模型。

Spring Framework 5.0 还支持 Spring TestContext Framework 中的并行测试执行。对于 Spring WebFlux, spring-test 同样包含 WebTestClient 的支持以集成测试支持 f或反应式编程模型 .

没有令人信服的理由为测试场景运行服务器。通过利用新的 WebTestClient,类似于 MockMvcWebTestClient 可以使用模拟请求和响应专门绑定到 WebFlux 服务器基础架构

Dropped or deprecated features

在 Spring 5.0 中,有一些包在 API 级别已被删除或弃用。 spring-aspects 模块的 mock.staticmock不再可用。 BeanFactoryLocator 也不能与 bean.factory.access 包一起使用。 NativeJdbcExtractor 也不再与 jdbc.support.nativejdbc 包一起提供。 web.view.tiles2orm.hibernate3orm.hibernate4 包也替换为 Tiles 3和休眠 5。

许多其他捆绑包,例如 JasperReports、Portlet、Velocity、JDO、Guava、< Span>XMLBeans 在 Spring 5 中不再受支持。我如果您正在使用上述任何捆绑包,建议您继续使用 Spring Framework 4.3.x。

Summary

在本章中,我们对 Spring Framework 的核心特性有了清晰的认识。我们还介绍了不同类型的 Spring 模块。之后,我们在 Spring Framework 中浏览了不同类型的 Spring 项目。我们还了解了 Spring IoC 容器的机制。在本章的最后,我们查看了 Spring 5.0 中引入的新特性和增强功能。

在下一章中,我们将详细了解 DI 的概念。我们还将介绍使用 DI 的不同类型的配置,包括性能评估。最后,我们将了解 DI 的陷阱。