提交 f2a8145b 编写于 作者: W wizardforcel

2021-10-05 22:19:27

上级 4f528ea8
......@@ -2512,7 +2512,7 @@ http://download.oracle.com/otn-pub/jcp/persistence-2_2-mrel-spec/JavaPersistence
* [甲骨文 TopLink](http://www.oracle.com/technetwork/middleware/toplink/overview/index.html)
* [JOOQ](https://www.jooq.org)
JPA 是围绕使用注释映射到数据库表的 Java bean 而设计的。或者,可以使用 XML 或两者的组合来定义映射。XML 定义的映射将取代注释定义的映射。该规范还为静态和动态数据查询定义了类似 SQL 的查询语言。
JPA 是围绕使用注释映射到数据库表的 Java Bean 而设计的。或者,可以使用 XML 或两者的组合来定义映射。XML 定义的映射将取代注释定义的映射。该规范还为静态和动态数据查询定义了类似 SQL 的查询语言。
大多数 JPA 实现都允许使用注释和 XML 定义的映射创建数据库模式。
......
......@@ -73,7 +73,7 @@ SpringBoot 支持 Maven 和 Gradle 作为其构建工具,我们将在我们的
我们将不讨论 SpringBoot 或其他 Spring 库的工作。Spring Boot 创建了一个在默认端口上运行的嵌入式 Tomcat,即`8080`。然后,它使用`@SpringBootApplication`注释注册类的包和子包中可用的所有控制器、组件和服务。
在我们的配方中,`com.packt.boot_demo`包中的`BootDemoApplication`类用`@SpringBootApplication`注释。因此,所有用`@Controller``@Service``@Configuration``@Component`注释的类都作为 bean 在 Spring 框架中注册并由它管理。现在,可以使用`@Autowired`注释将它们注入到代码中。
在我们的配方中,`com.packt.boot_demo`包中的`BootDemoApplication`类用`@SpringBootApplication`注释。因此,所有用`@Controller``@Service``@Configuration``@Component`注释的类都作为 Bean 在 Spring 框架中注册并由它管理。现在,可以使用`@Autowired`注释将它们注入到代码中。
有两种方法可以创建 Web 控制器:
......@@ -330,7 +330,7 @@ values('David', 'John', 'Delhi');
您一定想知道到数据库的连接是如何实现的。其中一个 Spring Boot 自动配置类`DataSourceAutoConfiguration`通过使用您的`application.properties`文件中定义的`spring.datasource.*`属性进行设置,为我们提供一个`javax.sql.DataSource`实例。然后,MyBatis 库使用此`javax.sql.DataSource`对象为您提供`SqlSessionTemplate`的实例,这是我们的`PersonMapper`在引擎盖下使用的。
然后,我们使用`com.packt.boot_db_demo.PersonMapper`,通过使用`@AutoWired`将其注入`com.packt.boot_db_demo.PersonController`类。`@AutoWired`注释查找任何 Spring 管理的 bean,这些 bean 要么是确切类型的实例,要么是其实现。看看本章中的“创建一个简单的 Spring Boot 应用程序”配方,了解`@Controller`注释。
然后,我们使用`com.packt.boot_db_demo.PersonMapper`,通过使用`@AutoWired`将其注入`com.packt.boot_db_demo.PersonController`类。`@AutoWired`注释查找任何 Spring 管理的 Bean,这些 Bean 要么是确切类型的实例,要么是其实现。看看本章中的“创建一个简单的 Spring Boot 应用程序”配方,了解`@Controller`注释。
通过很少的配置,我们能够快速设置简单的 CRUD 操作。这就是 SpringBoot 为开发人员提供的灵活性和敏捷性!
......
......@@ -692,21 +692,21 @@ class LoginServiceSpyTest {
# 一言以蔽之
Spring 框架的核心技术被称为**控制反转****IoC**),这是在实际使用这些对象的类之外实例化对象的过程。这些对象在 Spring 行话中称为 bean 或组件,默认情况下创建为*单例*对象。负责创建 bean 的实体称为 SpringIOC 容器。这是通过**依赖项注入****DI**)实现的,这是提供一个对象的依赖项而不是自己构建它们的过程。
Spring 框架的核心技术被称为**控制反转****IoC**),这是在实际使用这些对象的类之外实例化对象的过程。这些对象在 Spring 行话中称为 Bean 或组件,默认情况下创建为*单例*对象。负责创建 Bean 的实体称为 SpringIOC 容器。这是通过**依赖项注入****DI**)实现的,这是提供一个对象的依赖项而不是自己构建它们的过程。
IoC 和 DI 经常互换使用。然而,如前一段所述,这些概念并不完全相同(IoC 是通过 DI 实现的)。
如本节下一部分所述,Spring 是一个模块化框架。`spring-context`模块中提供了 Spring 的核心功能(即 IoC)。该模块提供创建**应用上下文**的能力,即 Spring 的 DI 容器。在 Spring 中有许多不同的方法来定义应用程序上下文。以下是两种最重要的类型:
* `AnnotationConfigApplicationContext`:应用程序上下文,它接受带注释的类来标识要在容器中执行的 SpringBean。在这种类型的上下文中,bean 通过使用注释`@Component`注释普通类来标识。它不是唯一一个将类声明为 Springbean 的类。还有更多的原型注释:`@Controller`(表示层原型,用于 Web 模块,MVC)、`@Repository`(持久层原型,用于数据访问模块,称为 Spring 数据)和`@Service`(用于服务层)。这三个注释用于分离应用程序的各个层。最后,使用`@Configuration`注释的类允许通过使用`@Bean`注释方法来定义 Springbeans(这些方法返回的对象将是容器中的 Springbeans):
* `AnnotationConfigApplicationContext`:应用程序上下文,它接受带注释的类来标识要在容器中执行的 SpringBean。在这种类型的上下文中,Bean 通过使用注释`@Component`注释普通类来标识。它不是唯一一个将类声明为 SpringBean 的类。还有更多的原型注释:`@Controller`(表示层原型,用于 Web 模块,MVC)、`@Repository`(持久层原型,用于数据访问模块,称为 Spring 数据)和`@Service`(用于服务层)。这三个注释用于分离应用程序的各个层。最后,使用`@Configuration`注释的类允许通过使用`@Bean`注释方法来定义 Springbeans(这些方法返回的对象将是容器中的 Springbeans):
![](img/00105.jpeg)
用于定义 bean 的 Spring 原型
用于定义 Bean 的 Spring 原型
* `ClassPathXmlApplicationContext`:应用程序上下文,它接受在项目类路径中的 XML 文件中声明的 bean 定义。
* `ClassPathXmlApplicationContext`:应用程序上下文,它接受在项目类路径中的 XML 文件中声明的 Bean 定义。
Spring2.5 引入了基于注释的上下文配置。springioc 容器与配置元数据(即 bean 定义)的实际写入格式完全解耦。如今,许多开发人员选择基于注释的配置,而不是基于 XML 的配置。因此,在本书中,我们将在示例中仅使用基于注释的上下文配置。
Spring2.5 引入了基于注释的上下文配置。springioc 容器与配置元数据(即 Bean 定义)的实际写入格式完全解耦。如今,许多开发人员选择基于注释的配置,而不是基于 XML 的配置。因此,在本书中,我们将在示例中仅使用基于注释的上下文配置。
让我们看一个简单的例子。首先,我们需要在我们的项目中包含`spring-context`依赖项。例如,作为 Maven 依赖项:
......@@ -718,7 +718,7 @@ Spring2.5 引入了基于注释的上下文配置。springioc 容器与配置元
</dependency>
```
然后,我们创建一个可执行的 Java 类(即,使用 main 方法)。注意,在这个类中,类级别有一个注释:`@ComponentScan`。这是 Spring 中非常重要的注释,因为它允许声明 Spring 将在其中以注释的形式查找 bean 定义的包。如果未定义特定的包(如示例中所示),则将从声明此注释的类的包(在示例中为包`io.github.bonigarcia`)进行扫描。在 main 方法的主体中,我们使用`AnnotationConfigApplicationContext`创建 Spring 应用程序上下文。从该上下文中,我们得到了类为`MessageComponent`的 Spring 组件,并将其`getMessage()`方法的结果写入标准输出:
然后,我们创建一个可执行的 Java 类(即,使用 main 方法)。注意,在这个类中,类级别有一个注释:`@ComponentScan`。这是 Spring 中非常重要的注释,因为它允许声明 Spring 将在其中以注释的形式查找 Bean 定义的包。如果未定义特定的包(如示例中所示),则将从声明此注释的类的包(在示例中为包`io.github.bonigarcia`)进行扫描。在 main 方法的主体中,我们使用`AnnotationConfigApplicationContext`创建 Spring 应用程序上下文。从该上下文中,我们得到了类为`MessageComponent`的 Spring 组件,并将其`getMessage()`方法的结果写入标准输出:
```java
package io.github.bonigarcia;
......@@ -796,7 +796,7 @@ public class MessageService {
}
```
现在,如果我们执行本例的主类(称为`MySpringApplication`,请参见此处的源代码),我们将创建一个基于注释的应用程序上下文,并尝试使用资源(这样,应用程序上下文将在最后关闭)。Spring IoC 容器将创建两个 bean:`MessageService``MessageComponet`。使用应用程序上下文,我们寻找 bean`MessageComponet`并调用其方法`getMessage`,最终写入标准输出:
现在,如果我们执行本例的主类(称为`MySpringApplication`,请参见此处的源代码),我们将创建一个基于注释的应用程序上下文,并尝试使用资源(这样,应用程序上下文将在最后关闭)。Spring IoC 容器将创建两个 Bean:`MessageService``MessageComponet`。使用应用程序上下文,我们寻找 Bean`MessageComponet`并调用其方法`getMessage`,最终写入标准输出:
```java
package io.github.bonigarcia;
......@@ -839,7 +839,7 @@ Spring 框架是模块化的,允许开发人员只使用框架提供的所需
Spring 是一个名为`spring-test`的模块,支持 Spring 组件的单元测试和集成测试。在其他特性中,该模块提供了创建用于测试目的的 Spring 应用程序上下文的能力,或者创建用于单独测试代码的模拟对象的能力。有不同的注释支持此测试功能。最重要的一项清单如下:
* `@ContextConfiguration`:此注释用于确定如何为集成测试加载和配置`ApplicationContext`。例如,它允许从注释类(使用元素类)或 XML 文件中声明的 bean 定义(使用元素位置)加载应用程序上下文。
* `@ContextConfiguration`:此注释用于确定如何为集成测试加载和配置`ApplicationContext`。例如,它允许从注释类(使用元素类)或 XML 文件中声明的 Bean 定义(使用元素位置)加载应用程序上下文。
* `@ActiveProfiles`:此注释用于指示容器在应用程序上下文加载期间应激活哪些定义配置文件(例如,开发和测试配置文件)。
* `@TestPropertySource`:此注释用于配置属性文件的位置和要添加的内联属性。
* `@WebAppConfiguration`:此注释用于指示Spring上下文`ApplicationContext`加载的是`WebApplicationContext.`
......@@ -877,9 +877,9 @@ Spring 是一个名为`spring-test`的模块,支持 Spring 组件的单元测
有关 Spring Boot 的完整信息,请访问[官方参考资料](https://projects.spring.io/spring-boot/)
SpringBoot 提供了不同的功能来简化测试。例如,它提供了`@SpringBootTest`注释,用于测试类的类级别。此注释将为这些测试创建`ApplicationContext`(与`@ContextConfiguration`类似,但用于基于 SpringBoot的应用程序)。正如我们在前面的章节中所看到的,`spring-test`模块中,我们使用注释`@ContextConfiguration(classes=… )`来指定要加载的 bean 定义(Spring`@Configuration`。在测试 SpringBoot应用程序时,这通常不是必需的。SpringBoot 的测试注释将自动搜索主配置(如果没有明确定义)。搜索算法从包含测试的包开始,直到找到一个`@SpringBootApplication`注释类。
SpringBoot 提供了不同的功能来简化测试。例如,它提供了`@SpringBootTest`注释,用于测试类的类级别。此注释将为这些测试创建`ApplicationContext`(与`@ContextConfiguration`类似,但用于基于 SpringBoot的应用程序)。正如我们在前面的章节中所看到的,`spring-test`模块中,我们使用注释`@ContextConfiguration(classes=… )`来指定要加载的 Bean 定义(Spring`@Configuration`。在测试 SpringBoot应用程序时,这通常不是必需的。SpringBoot 的测试注释将自动搜索主配置(如果没有明确定义)。搜索算法从包含测试的包开始,直到找到一个`@SpringBootApplication`注释类。
SpringBoot 还促进了对 Spring 组件使用模拟。为此,提供了注释`@MockBean`。此注释允许在`ApplicationContext`中为 bean 定义 Mockito mock。它可以是新的 bean,但也可以替换单个现有的 bean 定义。模拟 bean 在每个测试方法之后自动重置。这种方法通常被称为容器内测试,与容器外测试相对应,其中使用模拟库(例如,Mockito)对Spring组件进行单元测试,以隔离,而不需要Spring`ApplicationContext`。例如,Spring 应用程序的两种单元测试的示例将在下一节中显示。
SpringBoot 还促进了对 Spring 组件使用模拟。为此,提供了注释`@MockBean`。此注释允许在`ApplicationContext`中为 Bean 定义 Mockito mock。它可以是新的 Bean,但也可以替换单个现有的 Bean 定义。模拟 Bean 在每个测试方法之后自动重置。这种方法通常被称为容器内测试,与容器外测试相对应,其中使用模拟库(例如,Mockito)对Spring组件进行单元测试,以隔离,而不需要Spring`ApplicationContext`。例如,Spring 应用程序的两种单元测试的示例将在下一节中显示。
# 用于 Spring 的 JUnit5 扩展
......@@ -920,7 +920,7 @@ class SimpleSpringTest {
}
```
这是一个非常简单的示例,其中评估了名为`MessageComponent`的Spring组件。当本测试开始时,我们的`ApplicationContext`启动,所有Spring组件都在里面。之后,在本例中,将 bean`MessageComponent`注入测试中,只需调用方法`getMessage()`并验证其响应即可对其进行评估。
这是一个非常简单的示例,其中评估了名为`MessageComponent`的Spring组件。当本测试开始时,我们的`ApplicationContext`启动,所有Spring组件都在里面。之后,在本例中,将 Bean`MessageComponent`注入测试中,只需调用方法`getMessage()`并验证其响应即可对其进行评估。
值得回顾一下此测试需要哪些依赖项。使用 Maven 时,这些依赖项如下所示:
......
......@@ -133,9 +133,9 @@ dependencies {
我们应该从定义表示数据存储模式的 JavaBean 开始。它没有什么特别之处,所以我们将仅用一个注释跳过这一部分。
不要花太多时间为 Java 样板代码定义规范。我们的 bean 实现包含覆盖的`equals``hashCode`。它们都是 IDEA 自动生成的,不提供实际值,只是为了满足比较两个相同类型对象的需要(我们稍后将在规范中使用这种比较)。TDD 应该帮助我们更好地设计和编写更好的代码。编写 15-20 个规范来定义可由 IDE 自动编写的样板代码(如`equals`方法的情况)无助于我们实现这些目标。掌握 TDD 不仅意味着学习如何编写规范,还意味着知道什么时候不值得。
不要花太多时间为 Java 样板代码定义规范。我们的 Bean 实现包含覆盖的`equals``hashCode`。它们都是 IDEA 自动生成的,不提供实际值,只是为了满足比较两个相同类型对象的需要(我们稍后将在规范中使用这种比较)。TDD 应该帮助我们更好地设计和编写更好的代码。编写 15-20 个规范来定义可由 IDE 自动编写的样板代码(如`equals`方法的情况)无助于我们实现这些目标。掌握 TDD 不仅意味着学习如何编写规范,还意味着知道什么时候不值得。
也就是说,请参考源代码以查看 bean 规范和实现的完整性。
也就是说,请参考源代码以查看 Bean 规范和实现的完整性。
源代码可以在`tdd-java-ch06-tic-tac-toe-mongo`Git 库的[`01-bean`分支中找到](https://bitbucket.org/vfarcic/tdd-java-ch06-tic-tac-toe-mongo/branch/01-bean)。具体类别为`TicTacToeBeanSpec``TicTacToeBean`
......@@ -355,7 +355,7 @@ Argument(s) are different! Wanted:
mongoCollection.save(Turn: 3; X: 2; Y: 1; Player: Y);
```
这次我们调用的是预期的方法,但传递给它的参数并不是我们所希望的。在规范中,我们将期望值设置为 bean(new`TicTacToeBean(3, 2, 1, 'Y')`),在实现中,我们传递 null。不仅如此,Mockito 验证还可以告诉我们是否调用了正确的方法,以及传递给该方法的参数是否正确。
这次我们调用的是预期的方法,但传递给它的参数并不是我们所希望的。在规范中,我们将期望值设置为 Bean(new`TicTacToeBean(3, 2, 1, 'Y')`),在实现中,我们传递 null。不仅如此,Mockito 验证还可以告诉我们是否调用了正确的方法,以及传递给该方法的参数是否正确。
规范的正确实施如下所示:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册