2024最新Spring Framework入门教程(新手必看)
欢迎来到2024年!如果你是一位Java开发者,渴望在职业生涯中迈出坚实的一步,那么掌握Spring Framework无疑是你的必经之路。在当今的企业级Java开发中,Spring已经成为事实上的行业标准。它如同一位技艺精湛的管家,为你处理了应用开发中大量繁琐的底层工作,让你能更专注于业务逻辑的实现。
这篇文章是为纯粹的新手量身打造的。我们将抛开历史包袱,直接从最现代、最高效的开发方式——Spring Boot入手,来学习整个Spring生态的核心思想。本文预计阅读时间较长,内容详尽,请准备好你的IDE和一杯咖啡,让我们开始这段激动人心的旅程。
目录
-
第一章:思想启蒙 – 为什么要学习Spring?
- Spring是什么?一个通俗易懂的比喻
- 2024年,我们为什么选择从Spring Boot开始?
- Spring的核心思想:IoC与AOP
-
第二章:环境搭建 – 工欲善其事,必先利其器
- 必备工具清单 (JDK, Maven, IDE)
- 使用Spring Initializr创建你的第一个项目
-
第三章:初试牛刀 – 编写你的第一个Spring应用
- 项目结构概览
- 创建你的第一个“Hello, World”接口
- 运行与测试
-
第四章:深入核心 – 理解Spring的魔法
- Bean与Spring容器:应用的主体与管理者
- 依赖注入 (DI):Spring如何帮你“组装”应用
- 构造函数注入 (推荐)
- Setter注入
- 字段注入
- 组件扫描与常用注解:
@Component
,@Service
,@Repository
,@RestController
- 配置与
@Bean
注解:自定义你的“零件”
-
第五章:实战进阶 – 构建一个简单的Web应用
- 分层架构:Controller, Service, Repository
- 处理外部配置:
application.properties
与@Value
- 更优雅的配置方式:
@ConfigurationProperties
-
第六章:展望未来 – Spring生态一览
- 数据持久化:Spring Data JPA
- 安全框架:Spring Security
- 微服务:Spring Cloud
- 下一步学习路线图
-
总结
第一章:思想启蒙 – 为什么要学习Spring?
Spring是什么?一个通俗易懂的比喻
想象一下,你要盖一栋房子。
- 没有框架的开发:你需要自己去和水泥、砌砖、架设钢筋、铺设水电管道……你需要关心每一个细节,不仅耗时耗力,而且很容易出错。
- 使用Spring框架开发:你如同拥有了一个全能的建筑团队和一套预制好的高质量建筑模块(地基、墙体、屋顶、水电系统)。你只需要告诉团队:“我需要一个三室一厅的房子,主卧朝南,厨房要开放式。” 团队就会自动帮你把所有模块组装好,并处理好它们之间的连接问题。你,作为“总设计师”,只需要专注于“设计”这个核心工作。
Spring就是这个“全能建筑团队”。它是一个开源的、轻量级的Java应用开发框架,其目标是简化企业级Java应用的开发。它通过提供一整套基础设施,解决了开发的通用问题(如对象创建、依赖管理、事务处理、Web交互等),让开发者可以聚焦于业务逻辑本身。
2024年,我们为什么选择从Spring Boot开始?
在早期,配置Spring是一项复杂的工作,需要编写大量的XML文件来告诉Spring如何“组装”你的应用。这劝退了无数新手。
Spring Boot的出现彻底改变了这一切。它是Spring团队提供的一套“脚手架”,旨在极速、简化地创建独立的、生产级的Spring应用。
它的核心优势是:
1. 自动配置 (Auto-Configuration):Spring Boot会根据你项目中引入的依赖(比如引入了Web相关的jar包),自动为你配置好大部分所需的设置。你几乎可以“开箱即用”。
2. 起步依赖 (Starter Dependencies):提供了一系列spring-boot-starter-*
依赖包。例如,你只需要引入spring-boot-starter-web
,它就会自动帮你把构建Web应用所需的所有相关依赖(如Tomcat服务器、Spring MVC等)全部导入。
3. 内嵌服务器:无需再部署WAR包到外部的Tomcat服务器。Spring Boot应用内置了Tomcat、Jetty或Undertow,你可以直接打包成一个jar文件,通过java -jar
命令就能运行。
4. 无代码生成和XML配置:推崇基于Java注解的配置方式,告别繁琐的XML。
因此,在2024年,学习Spring的最佳路径就是从Spring Boot开始。它让你能快速看到成果,建立信心,然后再逐步深入理解其背后的Spring Framework原理。
Spring的核心思想:IoC与AOP
这是Spring框架的灵魂,理解它们至关重要。
-
控制反转 (Inversion of Control – IoC)
- 传统方式:你需要一个
UserService
对象,你就会在代码里new UserService()
。对象的创建和控制权在你(开发者)手里。 - IoC方式:你不再自己
new
对象了。你只需要告诉Spring:“我需要一个UserService
的实例”。Spring会在启动时创建好这个对象,并在你需要它的时候主动提供给你。对象的创建和管理的控制权从你手中反转到了Spring容器手中。 - 依赖注入 (Dependency Injection – DI) 是实现IoC最主要的方式。我们稍后会详细讲解。
- 传统方式:你需要一个
-
面向切面编程 (Aspect-Oriented Programming – AOP)
- 想象一下,你的应用中有很多方法都需要记录日志、检查权限、处理事务。如果每个方法都写一遍这些重复的代码,会非常冗余且难以维护。
- AOP允许你将这些横切关注点 (Cross-Cutting Concerns)(如日志、安全、事务)从主业务逻辑中分离出来,形成一个独立的“切面 (Aspect)”。然后,你可以定义一个规则(比如“所有以
Service
结尾的类中的所有公共方法”),Spring就会自动将这个“切面”应用到所有符合规则的地方。 - 这就像给你的代码批量加上了“装饰”,而无需修改原始代码,极大地提高了代码的模块化和可维护性。
第二章:环境搭建 – 工欲善其事,必先利其器
必备工具清单
- JDK (Java Development Kit):Spring Boot 3.x 要求 JDK 17或更高版本。请确保你的Java版本符合要求。在命令行输入
java -version
检查。 - 构建工具 (Maven或Gradle):用于管理项目依赖和构建过程。本文将使用Maven,它是Java世界中最流行的构建工具之一。确保已安装并配置好环境变量。在命令行输入
mvn -v
检查。 - IDE (Integrated Development Environment):一个好的IDE能极大提升开发效率。强烈推荐 IntelliJ IDEA (Community或Ultimate版均可) 或 Visual Studio Code (配合Spring Boot Extension Pack)。
使用Spring Initializr创建你的第一个项目
Spring Initializr (https://start.spring.io/) 是一个官方提供的Web工具,用于快速生成Spring Boot项目骨架。
请按照以下步骤操作:
- 打开浏览器,访问 https://start.spring.io/。
- 配置项目元数据:
- Project: 选择 Maven
- Language: 选择 Java
- Spring Boot: 选择最新的稳定版本(非SNAPSHOT),例如
3.2.5
。 - Project Metadata:
- Group: 通常是你的公司或组织的域名倒写,例如
com.example
。 - Artifact: 你的项目名称,例如
demo-spring-tutorial
。 - Name: 同Artifact。
- Description: 项目描述。
- Package name: 会根据Group和Artifact自动生成,例如
com.example.demospringtutorial
。
- Group: 通常是你的公司或组织的域名倒写,例如
- Packaging: 选择 Jar。
- Java: 选择 17 或更高版本。
- 添加依赖 (Dependencies):
- 点击右侧的 “ADD DEPENDENCIES…” 按钮。
- 搜索并添加 “Spring Web”:这是构建Web应用,包括RESTful应用的核心依赖。
- (可选,但强烈推荐)搜索并添加 “Lombok”:一个神奇的库,可以通过注解自动生成
getter
,setter
,toString
等样板代码,让你的代码更简洁。
-
生成项目:
- 点击底部的 “GENERATE” 按钮。
- 浏览器会下载一个
.zip
压缩包。
-
导入项目:
- 解压下载的
zip
文件。 - 打开你的IntelliJ IDEA,选择
File -> Open...
,然后选择你刚刚解压的文件夹。 - IDEA会自动识别为Maven项目并开始下载所有需要的依赖。这个过程可能需要一些时间,请耐心等待右下角的进度条完成。
- 解压下载的
第三章:初试牛刀 – 编写你的第一个Spring应用
项目导入成功后,我们来看看它的结构。
项目结构概览
demo-spring-tutorial
├── .mvn/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/example/demospringtutorial/
│ │ │ └── DemoSpringTutorialApplication.java // Spring Boot启动类
│ │ └── resources/
│ │ ├── static/ // 存放静态资源, 如CSS, JS, 图片
│ │ ├── templates/ // 存放模板文件, 如Thymeleaf
│ │ └── application.properties // 核心配置文件
│ └── test/
│ └── java/
│ └── com/example/demospringtutorial/
│ └── DemoSpringTutorialApplicationTests.java // 测试类
├── .gitignore
├── HELP.md
└── pom.xml // Maven项目配置文件,定义了依赖和构建规则
DemoSpringTutorialApplication.java
: 这是程序的入口。它包含一个main
方法,并且有一个@SpringBootApplication
注解,这个注解是Spring Boot魔法的起点。application.properties
: 这是Spring Boot的主要配置文件,你可以在这里配置服务器端口、数据库连接、自定义属性等。pom.xml
: 定义了项目的所有依赖(比如我们之前选的spring-boot-starter-web
)和插件。
创建你的第一个“Hello, World”接口
我们的目标是创建一个HTTP接口,当用户访问 http://localhost:8080/hello
时,会返回字符串 “Hello, Spring World!”。
- 在
com.example.demospringtutorial
包下,右键 ->New
->Java Class
。 - 创建一个名为
HelloController
的新类。 - 将以下代码复制到
HelloController.java
文件中:
“`java
package com.example.demospringtutorial;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController // (1)
public class HelloController {
@GetMapping("/hello") // (2)
public String sayHello() {
return "Hello, Spring World!"; // (3)
}
}
“`
代码解释:
1. @RestController
: 这是一个组合注解,它告诉Spring这个类是一个控制器。它的所有方法返回的都是数据(如JSON、XML或普通字符串),而不是视图(如HTML页面)。它等同于@Controller
+ @ResponseBody
。
2. @GetMapping("/hello")
: 这个注解将HTTP的GET请求映射到sayHello()
方法上。括号里的"/hello"
是URL路径。当有GET请求访问/hello
时,这个方法就会被调用。
3. return "Hello, Spring World!";
: 方法返回一个简单的字符串。由于有@RestController
注解,Spring会直接将这个字符串作为HTTP响应体返回给客户端。
运行与测试
- 运行应用:
- 找到
DemoSpringTutorialApplication.java
文件。 - 你会看到
main
方法旁边有一个绿色的播放按钮,点击它并选择 “Run ‘DemoSpringTutorialApplication'”。 - 或者,在项目根目录下打开终端,运行命令:
mvn spring-boot:run
。
- 找到
- 观察控制台:
- 你会看到Spring Boot的启动日志,最后几行会显示类似
Tomcat started on port(s): 8080 (http)
的信息。这表示内嵌的Tomcat服务器已经成功在8080端口启动。
- 你会看到Spring Boot的启动日志,最后几行会显示类似
- 测试接口:
- 打开你的浏览器(Chrome, Firefox等)。
- 在地址栏输入:
http://localhost:8080/hello
并回车。 - 页面上应该会显示:
Hello, Spring World!
恭喜你!你已经成功创建并运行了你的第一个Spring Boot应用!
第四章:深入核心 – 理解Spring的魔法
我们刚才只是“知其然”,现在要开始“知其所以然”。
Bean与Spring容器:应用的主体与管理者
- Bean: 在Spring的世界里,一个由Spring容器创建、管理和装配的对象,就被称为一个Bean。我们刚才创建的
HelloController
,在Spring启动时,就被Spring自动识别并创建了一个实例,这个实例就是一个Bean。 - Spring容器 (ApplicationContext): 它是Spring应用的核心,也常被称为IoC容器。它负责整个应用的生命周期,包括:
- 创建Bean。
- 将Bean装配在一起(即依赖注入)。
- 管理Bean的完整生命周期(从创建到销毁)。
@SpringBootApplication
注解背后就包含了启动和配置这个容器的逻辑。
依赖注入 (DI):Spring如何帮你“组装”应用
依赖注入是IoC的具体实现。假设我们的HelloController
需要一个GreetingService
来生成问候语。
- 创建
GreetingService
在com.example.demospringtutorial
包下创建一个新类GreetingService.java
:
“`java
package com.example.demospringtutorial;
import org.springframework.stereotype.Service; // (1)
@Service // (2)
public class GreetingService {
public String getGreeting() {
return "Hello from the Greeting Service!";
}
}
``
org.springframework.stereotype.Service
解释:
1. 我们引入了。
@Service`注解:这是一个构造型注解。它告诉Spring:“这个类是一个服务层组件,请为我创建一个Bean并交由你管理。”
2.
- 在
HelloController
中注入GreetingService
修改HelloController.java
:
“`java
package com.example.demospringtutorial;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
private final GreetingService greetingService; // (1)
// (2) 使用构造函数进行注入
public HelloController(GreetingService greetingService) {
this.greetingService = greetingService;
}
@GetMapping("/hello")
public String sayHello() {
// (3) 使用注入的Service
return greetingService.getGreeting();
}
}
``
GreetingService
解释:
1. 我们声明了一个类型的**final**字段。使用
final可以确保依赖在构造后不会被改变,是良好的实践。
GreetingService
2. 我们创建了一个**公共构造函数**,它的参数是。
sayHello
3. 在方法中,我们调用了
greetingService`的方法。
背后发生了什么?
* Spring启动时,扫描到@Service
注解,创建了一个GreetingService
的Bean。
* 接着,Spring扫描到@RestController
注解,准备创建HelloController
的Bean。
* Spring发现HelloController
只有一个构造函数,并且这个构造函数需要一个GreetingService
类型的参数。
* Spring容器自动在自己管理的Bean中查找GreetingService
的实例,找到了刚刚创建的那个。
* Spring将GreetingService
的实例作为参数传入构造函数,从而完成了HelloController
的创建。
这个过程就是依赖注入。HelloController
依赖GreetingService
,但它自己不负责创建GreetingService
,而是由外部的Spring容器“注入”进来。
为什么推荐构造函数注入?
* 依赖明确:构造函数清晰地表明了这个类需要哪些依赖才能工作。
* 不可变性:可以声明final
字段,保证依赖一旦注入就不会被修改。
* 易于测试:在单元测试中,你可以轻松地new HelloController(new MockGreetingService())
,传入一个模拟的Service
对象,而无需启动整个Spring容器。
组件扫描与常用注解
Spring如何知道要去创建哪些Bean呢?答案是组件扫描 (Component Scanning)。
@SpringBootApplication
注解内部包含了一个@ComponentScan
。默认情况下,它会扫描启动类所在的包及其所有子包下的所有组件。
除了@Service
,还有其他常用的构造型注解:
* @Component
: 最通用的注解,任何你想让Spring管理的类都可以使用它。
* @Repository
: 通常用在数据访问层(DAO/Repository),它还能帮助转换特定于平台的数据库异常。
* @Controller
: 用于传统的Spring MVC,方法通常返回视图名。
* @RestController
: 我们已经用过,用于RESTful Web服务。
这些注解在功能上基本等同于@Component
,但它们提供了更好的语义,让代码的意图更清晰。
配置与@Bean
注解:自定义你的“零件”
有时候,你想让Spring管理的Bean来自于一个第三方库的类,你无法在那个类的源码上添加@Component
注解。这时,就需要使用Java配置。
- 创建一个配置类
AppConfig.java
:
“`java
package com.example.demospringtutorial;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
// 假设这是一个来自第三方库的类,我们无法修改它
class ExternalLibraryComponent {
private final String name;
public ExternalLibraryComponent(String name) {
this.name = name;
System.out.println("ExternalLibraryComponent created with name: " + name);
}
public String getName() {
return name;
}
}
@Configuration // (1)
public class AppConfig {
@Bean // (2)
public ExternalLibraryComponent myCustomBean() {
// (3) 你在这里拥有完全的控制权来创建和配置对象
return new ExternalLibraryComponent("MyCustomBeanInstance");
}
}
``
@Configuration
解释:
1.: 声明这个类是一个Spring配置类。
@Bean
2.: 告诉Spring,这个方法将返回一个对象,请将该对象注册为一个Bean。Bean的名称默认是方法名 (
myCustomBean)。
new`对象,并调用它的方法进行初始化。
3. 方法体内的代码就是创建Bean的逻辑。你可以自由地
现在,你可以在任何其他Spring管理的组件中注入这个ExternalLibraryComponent
了:
“`java
@RestController
public class AnotherController {
private final ExternalLibraryComponent customBean;
public AnotherController(ExternalLibraryComponent customBean) {
this.customBean = customBean;
}
@GetMapping("/custom")
public String getCustomBeanName() {
return "The custom bean name is: " + customBean.getName();
}
}
“`
重启应用,访问 http://localhost:8080/custom
,你会看到 The custom bean name is: MyCustomBeanInstance
。
第五章:实战进阶 – 构建一个简单的Web应用
现在我们把学到的知识整合起来,构建一个更真实的应用。
分层架构:Controller, Service, Repository
一个典型的Web应用通常遵循分层架构,以实现关注点分离:
- Controller层: 负责接收HTTP请求,调用Service层处理业务逻辑,然后将结果返回给客户端。它不关心业务的具体实现。
- Service层: 负责处理核心业务逻辑。它可能会协调多个Repository来完成一个任务。它不关心数据是怎么来的(数据库、缓存还是文件)。
- Repository层: 负责数据访问。与数据库、外部API等进行交互。
我们来模拟一个获取用户信息的场景(暂时不用数据库,只用内存模拟)。
- 创建Model (
User.java
)
“`java
package com.example.demospringtutorial.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data // Lombok注解,自动生成getter, setter, toString, equals, hashCode
@AllArgsConstructor // Lombok注解,生成全参构造函数
@NoArgsConstructor // Lombok注解,生成无参构造函数
public class User {
private Long id;
private String username;
private String email;
}
``
model`子包中)*
*(注意:将这个类放在一个新的
- 创建Repository (
UserRepository.java
)
“`java
package com.example.demospringtutorial.repository;
import com.example.demospringtutorial.model.User;
import org.springframework.stereotype.Repository;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
@Repository
public class UserRepository {
// 使用内存中的Map模拟数据库
private final Map
public UserRepository() {
// 初始化一些数据
userDatabase.put(1L, new User(1L, "alice", "[email protected]"));
userDatabase.put(2L, new User(2L, "bob", "[email protected]"));
}
public Optional<User> findById(Long id) {
return Optional.ofNullable(userDatabase.get(id));
}
}
``
repository`子包中)*
*(注意:将这个类放在一个新的
- 创建Service (
UserService.java
)
“`java
package com.example.demospringtutorial.service;
import com.example.demospringtutorial.model.User;
import com.example.demospringtutorial.repository.UserRepository;
import org.springframework.stereotype.Service;
import java.util.Optional;
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public Optional<User> getUserById(Long id) {
// 这里可以添加复杂的业务逻辑,比如检查用户状态、权限等
return userRepository.findById(id);
}
}
``
service`子包中)*
*(注意:将这个类放在一个新的
- 创建Controller (
UserController.java
)
“`java
package com.example.demospringtutorial.controller;
import com.example.demospringtutorial.model.User;
import com.example.demospringtutorial.service.UserService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(“/api/users”) // (1)
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping("/{id}") // (2)
public ResponseEntity<User> getUserById(@PathVariable Long id) { // (3)
return userService.getUserById(id)
.map(user -> ResponseEntity.ok(user)) // (4) 找到用户,返回200 OK
.orElse(ResponseEntity.notFound().build()); // (5) 没找到,返回404 Not Found
}
}
``
controller
*(注意:将这个类放在一个新的子包中)*
@RequestMapping(“/api/users”)
解释:
1.: 在类级别上定义一个基础路径。这个控制器下的所有接口URL都会以
/api/users开头。
@GetMapping(“/{id}”)
2.: 这里的
{id}是一个**路径变量**。
@PathVariable Long id
3.: 这个注解告诉Spring,将URL中
{id}部分的值,赋给方法的
id参数。
ResponseEntity
4.: 这是一个更强大的返回类型,它不仅包含响应体(数据),还包含了HTTP状态码和头信息。
ResponseEntity.ok(user)会创建一个状态码为200的响应。
.orElse(…)
5.: 如果
Optional`为空(即没找到用户),则执行这里的逻辑,创建一个状态码为404的响应。
重启应用,现在你可以测试新的接口了:
* 访问 http://localhost:8080/api/users/1
,你会得到一个包含alice信息的JSON。
* 访问 http://localhost:8080/api/users/99
,你会得到一个404错误。
处理外部配置:application.properties
与@Value
硬编码的字符串不是好习惯。我们可以在配置文件中定义一个自定义的欢迎语。
-
打开
src/main/resources/application.properties
,添加一行:
properties
app.welcome.message=Welcome to our awesome application! -
创建一个新的Controller来使用这个配置:
“`java
package com.example.demospringtutorial.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class WelcomeController {
@Value("${app.welcome.message}") // (1)
private String welcomeMessage;
@GetMapping("/welcome")
public String welcome() {
return welcomeMessage;
}
}
``
@Value(“${…}”)
解释:
1.注解可以将配置文件中的属性值注入到字段中。
${}`是占位符语法。
重启应用,访问 http://localhost:8080/welcome
,你将看到配置文件中的消息。
更优雅的配置方式:@ConfigurationProperties
当配置项很多时,使用@Value
会很零散。@ConfigurationProperties
可以将一组相关的配置项映射到一个Java对象上,实现类型安全的配置。这需要额外的依赖,但Spring Boot通常已经为你准备好了。
-
在
application.properties
中添加一组相关的配置:
properties
app.info.name=My Spring App
app.info.version=1.0.0
app.info.author=Spring Learner -
创建一个配置属性类 (
AppInfoProperties.java
):
“`java
package com.example.demospringtutorial.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = “app.info”) // (1)
public class AppInfoProperties {
private String name;
private String version;
private String author;
// Getters and Setters are required for binding
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getVersion() { return version; }
public void setVersion(String version) { this.version = version; }
public String getAuthor() { return author; }
public void setAuthor(String author) { this.author = author; }
}
``
@Data
*(注意:Lombok的在这里同样适用)*
@ConfigurationProperties(prefix = “app.info”)
解释:
1.告诉Spring Boot,将
application.properties中所有以
app.info开头的属性,绑定到这个类的字段上。字段名与属性名的后半部分(如
name`)对应。
- 启用这个配置属性类。在你的启动类或任何
@Configuration
类上添加注解:
“`java
// 在 DemoSpringTutorialApplication.java 中
import com.example.demospringtutorial.config.AppInfoProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@SpringBootApplication
@EnableConfigurationProperties(AppInfoProperties.class) // (2)
public class DemoSpringTutorialApplication {
// … main method
}
``
@EnableConfigurationProperties
解释:
2.注解会激活
@ConfigurationProperties功能,并将
AppInfoProperties`注册为一个Bean。
-
使用它:
“`java
@RestController
public class AppInfoController {
private final AppInfoProperties appInfo;public AppInfoController(AppInfoProperties appInfo) {
this.appInfo = appInfo;
}@GetMapping(“/info”)
public AppInfoProperties getAppInfo() {
return appInfo;
}
}
“`
重启应用,访问 http://localhost:8080/info
,你会看到一个包含所有应用信息的JSON对象。这种方式更结构化,更健壮,并且IDE会有很好的自动补全支持。
第六章:展望未来 – Spring生态一览
恭喜你,你已经掌握了Spring Boot开发的核心基础!这为你打开了通往整个Spring庞大生态系统的大门。以下是你接下来可以探索的方向:
- Spring Data JPA: 想要连接真正的数据库(如MySQL, PostgreSQL)?Spring Data JPA能极大地简化数据库操作。你只需要定义一个接口,它就能自动为你生成SQL实现。
- Spring Security: 任何严肃的应用都需要安全保障。Spring Security是一个功能强大且高度可定制的认证和授权框架。
- Spring Cloud: 如果你想构建微服务架构,Spring Cloud提供了一整套解决方案,包括服务发现、配置中心、网关、熔断器等。
- Spring MVC: 我们使用的
spring-boot-starter-web
底层就是Spring MVC。深入学习它可以让你更好地理解Web请求的处理流程、拦截器、过滤器等高级概念。 - Reactive Spring: 如果你对高并发、非阻塞式编程感兴趣,可以探索Spring WebFlux,它是Spring对响应式编程模型的支持。
总结
这篇教程带领你从零开始,通过现代化的Spring Boot方式,完成了从概念理解到实战开发的完整过程。让我们回顾一下关键知识点:
- Spring的核心是IoC和AOP,它通过DI解耦了组件,通过AOP分离了横切关注点。
- Spring Boot是入门Spring的最佳方式,它通过自动配置、起步依赖和内嵌服务器极大地简化了开发。
- 万物皆Bean:由Spring容器管理的对象都是Bean。我们通过
@Component
及其衍生注解(@Service
,@Repository
等)或@Bean
方法来声明Bean。 - 依赖注入是王道:优先使用构造函数注入来组装你的Bean,这让依赖关系更清晰,代码更健壮。
- 分层架构是基础:Controller, Service, Repository各司其职,让应用结构清晰,易于维护和测试。
- 配置是关键:学会使用
application.properties
,并通过@Value
和更强大的@ConfigurationProperties
来管理外部化配置。
Spring的学习曲线可能看起来很陡峭,但你已经迈出了最重要的一步。今天构建的这个简单应用,已经包含了现代Java后端开发中最核心、最常用的模式。以此为基础,不断实践、不断探索,你会发现Spring能为你带来的远不止于此。
现在,打开你的IDE,开始你的Spring编码之旅吧!