我们将不讨论 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`注释将它们注入到代码中。
您一定想知道到数据库的连接是如何实现的。其中一个 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`注释。
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 的配置。因此,在本书中,我们将在示例中仅使用基于注释的上下文配置。
然后,我们创建一个可执行的 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
packageio.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
packageio.github.bonigarcia;
...
...
@@ -839,7 +839,7 @@ Spring 框架是模块化的,允许开发人员只使用框架提供的所需
Spring 是一个名为`spring-test`的模块,支持 Spring 组件的单元测试和集成测试。在其他特性中,该模块提供了创建用于测试目的的 Spring 应用程序上下文的能力,或者创建用于单独测试代码的模拟对象的能力。有不同的注释支持此测试功能。最重要的一项清单如下:
*`@ContextConfiguration`:此注释用于确定如何为集成测试加载和配置`ApplicationContext`。例如,它允许从注释类(使用元素类)或 XML 文件中声明的 bean 定义(使用元素位置)加载应用程序上下文。
*`@ContextConfiguration`:此注释用于确定如何为集成测试加载和配置`ApplicationContext`。例如,它允许从注释类(使用元素类)或 XML 文件中声明的 Bean 定义(使用元素位置)加载应用程序上下文。