目录
Spring Boot中@RestController和@Controller注解有什么区别?
Spring的注解@requestBody和@responseBody的区别
Spring中常用的注解有哪些
项目启动相关注解
@SpringBootApplication
:这是一个组合注解,包含了@SpringBootConfiguration
、@EnableAutoConfiguration
和@ComponentScan
。它的作用是开启 Spring Boot 的自动配置功能,扫描组件并将当前类标记为配置类。通常会将其添加到主应用类上。
Bean 定义与管理注解
@Component
:这是一个通用注解,用于将类标记为 Spring Bean,让 Spring 能自动扫描并将其注册到应用上下文中。@Service
:它是@Component
的一种特殊形式,通常用于标记业务逻辑层的类。@Repository
:同样是@Component
的特殊形式,主要用于标记数据访问层(DAO)的类,还能处理数据访问异常。@Controller
:也是@Component
的特殊形式,用于标记控制器类,处理 HTTP 请求。@RestController
:这是@Controller
和@ResponseBody
的组合注解,用于创建 RESTful 风格的控制器。
依赖注入注解
@Autowired
:用于自动装配 Bean,可作用于构造函数、字段或方法上。@Qualifier
:当存在多个同类型的 Bean 时,可使用@Qualifier
指定要注入的 Bean 的名称。
配置相关注解
@Configuration
:用于标记配置类,替代传统的 XML 配置文件。配置类中可以包含@Bean
注解的方法。@Bean
:用于在配置类中定义 Bean,方法的返回值会被注册为 Spring Bean。@Value
:用于从配置文件(如application.properties
或application.yml
)中读取属性值。import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MyConfig { @Bean public MyComponent myComponent() { return new MyComponent(); } }
请求映射注解
@RequestMapping
:是一个通用的请求映射注解,可用于类和方法上,能指定请求的 URL、请求方法等。import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; @Controller @RequestMapping("/example") public class ExampleController { @RequestMapping(value = "/test", method = RequestMethod.GET) @ResponseBody public String test() { return "Test response"; } }
@GetMapping
、@PostMapping
、@PutMapping
、@DeleteMapping
、@PatchMapping
:它们是@RequestMapping
的快捷方式,分别对应 HTTP 的 GET、POST、PUT、DELETE 和 PATCH 请求方法。
Spring Boot中@RestController和@Controller注解有什么区别?
注解本质
@Controller
:它是 Spring 框架里的一个核心注解,继承自@Component
。其作用是把一个类标记为 Spring MVC 控制器,该类可处理 HTTP 请求。不过,它本身不会自动把方法返回值转换为 JSON 或 XML 等格式。@RestController
:这是 Spring 4.0 引入的一个组合注解,它结合了@Controller
和@ResponseBody
的功能。此注解会将类标记为控制器,同时默认把方法的返回值当作响应体返回,一般用于构建 RESTful 风格的 Web 服务。
返回值处理
@Controller
:当控制器方法返回一个字符串时,Spring 会将其视为视图名称,接着去查找对应的视图模板并进行渲染。如果要返回 JSON 或 XML 数据,就需要在方法上添加@ResponseBody
注解。@RestController
:其方法的返回值会直接作为响应体返回,无需额外添加@ResponseBody
注解。Spring 会根据HttpMessageConverter
把返回值转换为合适的格式(如 JSON、XML 等)
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MyViewController {
@GetMapping("/view")
public String getView() {
return "myView"; // 返回视图名称
}
@GetMapping("/data")
@ResponseBody
public String getData() {
return "{\"message\": \"Hello, World!\"}"; // 返回 JSON 数据
}
}
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyRestController {
@GetMapping("/rest")
public String getRestData() {
return "{\"message\": \"Hello, REST!\"}"; // 直接返回 JSON 数据
}
}
使用场景
@Controller
:常用于传统的 Spring MVC 应用,在这种应用中,控制器方法主要返回视图名称,由视图解析器负责渲染页面。@RestController
:适用于构建 RESTful 风格的 Web 服务,这类服务通常返回 JSON 或 XML 数据,供其他系统调用。
Spring的注解@requestBody和@responseBody的区别
功能用途
@RequestBody
:此注解用于将 HTTP 请求体中的内容绑定到方法的参数上。在处理 POST、PUT 等请求时,客户端通常会将数据放在请求体中发送到服务器,借助@RequestBody
注解,Spring 能把请求体中的数据自动转换为 Java 对象。@ResponseBody
:该注解用于将方法的返回值直接作为 HTTP 响应体返回给客户端。一般在构建 RESTful 服务时使用,Spring 会依据HttpMessageConverter
把返回的 Java 对象转换为合适的格式,如 JSON、XML 等。
使用位置
@RequestBody
:用在控制器方法的参数前@ResponseBody
:可放在控制器方法上,也能放在控制器类上。若放在类上,意味着该类中所有方法的返回值都会作为响应体返回。
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
@PostMapping("/example")
public String handleRequest(@RequestBody User user) {
return "Received user: " + user.getName();
}
}
class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyRestController {
@GetMapping("/data")
@ResponseBody
public User getData() {
User user = new User();
user.setName("John");
return user;
}
}
数据转换
@RequestBody
:Spring 会依据请求头中的Content-Type
来选择合适的HttpMessageConverter
进行数据转换。例如,若Content-Type
是application/json
,就会使用MappingJackson2HttpMessageConverter
把 JSON 数据转换为 Java 对象。@ResponseBody
:Spring 会根据请求头中的Accept
字段以及返回对象的类型,选择合适的HttpMessageConverter
进行数据转换。例如,若客户端期望的响应格式是application/json
,Spring 会使用MappingJackson2HttpMessageConverter
把 Java 对象转换为 JSON 数据。
总结
@RequestBody
用于从 HTTP 请求体中读取数据并转换为 Java 对象,处理请求端发送的数据。@ResponseBody
用于将 Java 对象转换为合适的格式并作为 HTTP 响应体返回给客户端,处理服务器返回的数据。在 Spring Boot 的@RestController
注解中,实际上已经包含了@ResponseBody
的功能。
说说@Bean和@componentscan的区别
功能用途
@Bean
:此注解用于在配置类里定义 Bean。当你需要手动创建一个 Bean 实例,并且对其创建过程进行精细控制时,就可以使用@Bean
注解。通常在配置类的方法上使用该注解,方法的返回值会被注册为 Spring Bean。@ComponentScan
:该注解的作用是告诉 Spring 去扫描指定包及其子包下的组件。Spring 会自动发现并注册带有@Component
、@Service
、@Repository
、@Controller
等注解的类为 Bean。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyConfig {
@Bean
public MyService myService() {
return new MyService();
}
}
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = "com.example.service")
public class AppConfig {
// 配置类内容
}
使用位置
@Bean
:一般用在@Configuration
注解标注的配置类的方法上。@ComponentScan
:通常用在@Configuration
注解标注的配置类上,也可以用在@SpringBootApplication
注解标注的主应用类上(因为@SpringBootApplication
包含了@ComponentScan
)。
Bean 创建方式
@Bean
:由开发者手动编写方法来创建 Bean 实例,能够在方法中添加自定义的逻辑,如初始化参数、调用其他方法等。@ComponentScan
:Spring 自动扫描并创建 Bean 实例,无需开发者手动编写创建代码。Spring 会根据类的构造函数和依赖关系来创建 Bean。
应用场景
@Bean
:适用于以下场景:- 引入第三方库的类,这些类没有使用 Spring 注解,需要手动将其注册为 Bean。
- 需要对 Bean 的创建过程进行复杂的初始化操作。
@ComponentScan
:适用于以下场景:- 项目中有大量的组件类,希望 Spring 自动扫描并注册这些组件。
- 开发自己的业务逻辑组件,如服务层、数据访问层等,使用
@Service
、@Repository
等注解标注后,通过@ComponentScan
自动注册。
总结
@Bean
侧重于手动定义和创建 Bean,给予开发者对 Bean 创建过程更多的控制。@ComponentScan
侧重于自动扫描和注册 Bean,简化了大量组件的注册过程。
简单介绍一下springboot
Spring Boot 是由 Pivotal 团队开发的一款用于简化 Spring 应用开发的框架,它基于 Spring 框架,旨在帮助开发者快速搭建和开发独立的、生产级别的 Spring 应用。以下从几个关键方面为你简单介绍 Spring Boot:
主要特点
- 快速搭建:提供了丰富的 Spring Boot Starter 依赖,通过在项目中添加相应的 Starter 依赖,就能快速集成各种功能,如 Web 开发、数据库访问、安全认证等,无需手动配置大量的依赖和 XML 文件。
- 自动配置:Spring Boot 会根据项目中添加的依赖,自动对 Spring 应用进行合理的默认配置,减少了开发者的配置工作量。例如,当添加了
spring-boot-starter-web
依赖后,Spring Boot 会自动配置嵌入式的 Tomcat 服务器和 Spring MVC。 - 嵌入式服务器:支持嵌入式的服务器,如 Tomcat、Jetty 或 Undertow,开发者可以将应用打包成可执行的 JAR 或 WAR 文件,直接运行,无需额外部署到外部服务器。
- 生产就绪:提供了一系列生产级别的特性,如健康检查、指标监控、外部化配置等,方便开发者在生产环境中对应用进行管理和监控。
- 无代码生成和 XML 配置:Spring Boot 倡导零配置原则,尽量避免使用代码生成和 XML 配置,使代码更加简洁和易于维护。
核心组件
- Spring Boot Starter:是一系列依赖的集合,每个 Starter 对应一个特定的功能模块,如
spring-boot-starter-web
用于开发 Web 应用,spring-boot-starter-data-jpa
用于使用 JPA 进行数据库访问。 - 自动配置模块:Spring Boot 的自动配置功能通过
@EnableAutoConfiguration
注解实现,它会根据类路径中的依赖和配置,自动配置 Spring 应用的各种组件。 - 嵌入式服务器:Spring Boot 内置了多种嵌入式服务器,开发者可以通过配置选择合适的服务器。例如,在
application.properties
或application.yml
中配置服务器的端口号等信息。 - Spring Boot Actuator:提供了生产级别的功能,如健康检查、指标监控、审计等。通过添加
spring-boot-starter-actuator
依赖,开发者可以方便地开启这些功能。
开发流程
- 创建项目:可以使用 Spring Initializr(https://start.spring.io/) 快速创建一个 Spring Boot 项目,选择所需的依赖和项目信息,生成项目骨架。
- 编写代码:在生成的项目中编写业务逻辑代码,使用 Spring Boot 提供的注解和功能进行开发。例如,使用
@RestController
注解创建 RESTful 控制器,使用@Service
注解创建业务逻辑服务。 - 配置应用:可以在
application.properties
或application.yml
中配置应用的各种参数,如数据库连接信息、服务器端口号等。 - 运行应用:可以直接在 IDE 中运行 Spring Boot 应用的主类,或者将应用打包成可执行的 JAR 或 WAR 文件,通过命令行运行。
Spring Boot有哪些常用的Starter依赖?
Web 开发相关
spring-boot-starter-web
:这是开发 Web 应用最基础的依赖,它集成了 Spring MVC、嵌入式的 Tomcat 服务器,能让你快速搭建基于 RESTful 的 Web 服务或者传统的 Web 应用。spring-boot-starter-webflux
:用于构建响应式 Web 应用,它基于 Reactor 项目,支持非阻塞、异步编程模型,适合处理高并发场景。
数据访问相关
spring-boot-starter-data-jpa
:集成了 Spring Data JPA 和 Hibernate,方便进行数据库的持久化操作。它支持多种数据库,能减少大量的样板代码。spring-boot-starter-data-mongodb
:用于集成 MongoDB 数据库,支持响应式和非响应式的操作方式,可快速实现与 MongoDB 的交互。spring-boot-starter-data-redis
:集成 Redis 缓存数据库,提供了 RedisTemplate 和 StringRedisTemplate 等工具类,方便进行缓存操作。
安全相关
spring-boot-starter-security
:为 Spring Boot 应用提供了全面的安全功能,包括身份验证、授权、密码加密等,能有效保护应用的安全性。
日志相关
spring-boot-starter-logging
:Spring Boot 默认的日志依赖,底层使用 Logback 实现,可方便地进行日志配置和管理。
测试相关
spring-boot-starter-test
:包含了多种测试框架,如 JUnit、Mockito、Spring Test 等,可用于编写和运行单元测试、集成测试等。
说说springboot的启动过程
Spring Boot 启动过程可以分为多个关键阶段,以下为你详细阐述其主要步骤:
1. 启动入口
Spring Boot 应用的启动通常从包含 main
方法的主类开始,主类上会添加 @SpringBootApplication
注解。例如:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
SpringApplication.run
方法是启动的核心入口,它接收主类和命令行参数作为输入。
2. 创建 SpringApplication 实例
在 SpringApplication.run
方法内部,首先会创建一个 SpringApplication
实例。在创建过程中,会进行以下操作:
- 推断应用类型:判断应用是 Web 应用(如 Servlet Web 应用或 Reactive Web 应用)还是非 Web 应用。
- 查找并加载初始化器(
ApplicationContextInitializer
):初始化器可以在ApplicationContext
创建后但未刷新之前对其进行定制化配置。 - 查找并加载监听器(
ApplicationListener
):监听器可以监听 Spring Boot 应用启动过程中的各种事件,如应用启动事件、应用就绪事件等。 - 推断主类:确定包含
main
方法的主类。
3. 准备环境
创建好 SpringApplication
实例后,会开始准备应用运行的环境。这一阶段会完成以下任务:
- 创建
ConfigurableEnvironment
实例:根据应用类型创建对应的环境对象,如StandardServletEnvironment
用于 Servlet Web 应用。 - 配置环境:加载配置文件(如
application.properties
、application.yml
)和命令行参数,将其添加到环境的属性源中。 - 触发
ApplicationEnvironmentPreparedEvent
事件:通知所有监听器环境已准备好。
4. 创建 ApplicationContext
根据之前推断的应用类型,创建相应的 ApplicationContext
实例。例如:
- 对于 Servlet Web 应用,创建
AnnotationConfigServletWebServerApplicationContext
实例。 - 对于 Reactive Web 应用,创建
AnnotationConfigReactiveWebServerApplicationContext
实例。 - 对于非 Web 应用,创建
AnnotationConfigApplicationContext
实例。
5. 准备 ApplicationContext
在 ApplicationConext
创建后,会进行一些准备工作:
- 设置环境:将之前准备好的环境对象设置到
ApplicationContext
中。 - 应用初始化器:调用之前加载的所有初始化器对
ApplicationContext
进行定制化配置。 - 触发
ApplicationContextInitializedEvent
事件:通知监听器ApplicationContext
已初始化。
6. 加载 Bean 定义
通过 @SpringBootApplication
注解及其包含的 @ComponentScan
注解,Spring Boot 会扫描指定包及其子包下的所有组件(如 @Component
、@Service
、@Repository
等注解标注的类),并将这些组件注册为 Bean 定义。同时,也会处理 @Configuration
注解标注的配置类,解析其中的 @Bean
方法,将其返回的对象注册为 Bean 定义。
7. 刷新 ApplicationContext
调用 ApplicationContext
的 refresh
方法,这是 Spring 容器初始化的核心步骤,会完成以下重要操作:
- 创建并初始化 BeanFactory:负责管理和创建所有的 Bean 实例。
- 注册 BeanPostProcessor:用于在 Bean 实例化前后进行额外的处理,如 AOP 代理的创建。
- 初始化消息源:用于国际化支持。
- 初始化事件广播器:用于发布应用事件。
- 创建嵌入式服务器(如果是 Web 应用):如 Tomcat、Jetty 或 Undertow,并启动服务器。
- 实例化所有单例 Bean:根据之前注册的 Bean 定义,创建并初始化所有单例 Bean。
- 触发
ApplicationReadyEvent
事件:表示应用已准备好接收请求。
8. 启动完成
当 ApplicationContext
刷新完成后,Spring Boot 应用启动成功,开始监听客户端请求(如果是 Web 应用),并可以正常提供服务。
综上所述,Spring Boot 启动过程是一个复杂且有序的过程,通过自动化配置和组件扫描等机制,大大简化了 Spring 应用的开发和部署。
Sprint boot自动装配原理
Spring Boot 自动装配主要依赖于以下几个核心注解:
@SpringBootApplication
:这是一个组合注解,包含了@SpringBootConfiguration
、@EnableAutoConfiguration
和@ComponentScan
。其中,@EnableAutoConfiguration
是开启自动装配的关键注解。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
@EnableAutoConfiguration
:该注解会导入AutoConfigurationImportSelector
类,借助这个类来加载自动配置类。
自动配置类的加载
AutoConfigurationImportSelector
类会在 Spring 应用启动时发挥作用,它的主要任务是加载自动配置类,具体步骤如下:
- 查找自动配置类:
AutoConfigurationImportSelector
会从META - INF/spring.factories
文件中查找所有的自动配置类。这个文件存在于各个 Spring Boot Starter 依赖的 JAR 包中,文件内容以键值对形式呈现,其中org.springframework.boot.autoconfigure.EnableAutoConfiguration
作为键,对应的值是一系列自动配置类的全限定名。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
- 过滤自动配置类:找到所有自动配置类后,
AutoConfigurationImportSelector
会根据一些条件对这些类进行过滤。例如,会检查@Conditional
注解及其派生注解(如@ConditionalOnClass
、@ConditionalOnMissingBean
等),只有当条件满足时,对应的自动配置类才会被加载。
条件注解的作用
条件注解是自动装配的重要组成部分,它能根据不同的条件决定是否加载某个自动配置类或创建某个 Bean。常见的条件注解如下:
@ConditionalOnClass
:当类路径中存在指定的类时,该条件才会满足。- @ConditionalOnMissingClass : classpath中不存在该类时起效
- @ConditionalOnBean : DI容器中存在该类型Bean时起效
- @ConditionalOnMissingBean : DI容器中不存在该类型Bean时起效
- @ConditionalOnSingleCandidate : DI容器中该类型Bean只有一个或 @Primary的只有一个时起效
- @ConditionalOnExpression : SpEL表达式结果为true时
- @ConditionalOnProperty : 参数设置或者值一致时起效
- @ConditionalOnResource : 指定的文件存在时起效
- @ConditionalOnJndi : 指定的JNDI存在时起效
- @ConditionalOnJava : 指定的Java版本存在时起效
- @ConditionalOnWebApplication : Web应用环境下起效
- @ConditionalOnNotWebApplication : 非Web应用环境下起效
自动配置的顺序
Spring Boot 会按照一定的顺序加载自动配置类,以确保配置的正确性。可以使用 @AutoConfigureOrder
或 @AutoConfigureBefore
、@AutoConfigureAfter
注解来调整自动配置类的加载顺序。
总结
Spring Boot 自动装配的原理是通过 @EnableAutoConfiguration
注解导入 AutoConfigurationImportSelector
类,从 META - INF/spring.factories
文件中查找自动配置类,再根据条件注解对这些类进行过滤和加载,从而实现自动配置 Spring 应用的功能。
Springboot中如何管理异常或者日志
1. 使用 @ExceptionHandler
处理控制器内异常
@ExceptionHandler
注解能在控制器类里定义异常处理方法,该方法可处理该控制器中所有方法抛出的指定类型的异常。
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
@GetMapping("/example")
public String example() {
throw new RuntimeException("Something went wrong");
}
@ExceptionHandler(RuntimeException.class)
public ResponseEntity<String> handleRuntimeException(RuntimeException e) {
return new ResponseEntity<>("Error: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
2. 使用 @ControllerAdvice
进行全局异常处理
@ControllerAdvice
注解能定义一个全局的异常处理类,其中的 @ExceptionHandler
方法可处理所有控制器抛出的指定类型的异常。
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleException(Exception e) {
return new ResponseEntity<>("Global Error: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
3. 使用 @ResponseStatus
注解
@ResponseStatus
注解可用于异常类,指定当该异常抛出时应返回的 HTTP 状态码。
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String message) {
super(message);
}
}
在控制器方法中抛出该异常:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyRestController {
@GetMapping("/resource")
public String getResource() {
throw new ResourceNotFoundException("Resource not found");
}
}
日志管理
1. Spring Boot 默认日志框架
Spring Boot 默认使用 Logback 作为日志框架,无需额外配置即可使用。可以在 application.properties
或 application.yml
中配置日志级别。
# application.properties
logging.level.root=INFO
logging.level.com.example=DEBUG
yaml
# application.yml
logging:
level:
root: INFO
com.example: DEBUG
2. 自定义日志配置文件
可以创建自定义的 Logback 配置文件 logback.xml
来对日志进行更细致的配置。
xml
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="CONSOLE" />
</root>
</configuration>
3. 集成其他日志框架
若要使用其他日志框架,如 Log4j2,需要排除默认的 Logback 依赖,然后添加 Log4j2 的依赖。
xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
</dependencies>
接着在 application.properties
或 application.yml
中配置 Log4j2。
通过以上方法,你可以在 Spring Boot 中有效地管理异常和日志。