1、概览 本文将带你了解如何使用 ResponseEntity 设置 HTTP 响应的 Body、Status 和 Header。
2、ResponseEntity ResponseEntity 表示整个 HTTP 响应:状态码、Header 和 Body。因此,可以用它来完全配置 HTTP 响应。只需从端点返回它,Spring 就会处理接下来的所有事情。
ResponseEntity 是一个泛型类。因此,可以使用任何类型作为响应体:
@GetMapping("/hello") ResponseEntity<String> hello() { return new ResponseEntity<>("Hello World!", HttpStatus.OK); } 通过编程式,可以针对不同情况返回不同的 HTTP 状态码:
@GetMapping("/age") ResponseEntity<String> age( @RequestParam("yearOfBirth") int yearOfBirth) { if (isInFuture(yearOfBirth)) { return new ResponseEntity<>( "Year of birth cannot be in the future", HttpStatus.BAD_REQUEST); // 400 } return new ResponseEntity<>( "Your age is " + calculateAge(yearOfBirth), HttpStatus.OK); // 200s } 还可以设置 HTTP 响应头:
1、概览 本文将带你了解 Spring 中 @RequestParam 注解的用法。
简单地说,可以使用 @RequestParam 从请求中提取查询参数、表单参数甚至是多个参数。
2、示例端点 假设我们有一个端点 /api/foos,它接受一个名为 id 的查询参数:
@GetMapping("/api/foos") @ResponseBody public String getFoos(@RequestParam String id) { return "ID: " + id; } 在本例中,使用 @RequestParam 来提取 id 查询参数。
通过 GET 请求来调用 getFoos:
http://localhost:8080/spring-mvc-basics/api/foos?id=abc ---- ID: abc 接下来,看看注解的属性:name、value、required 和 defaultValue。
3、指定请求参数名称 在上一个示例中,变量名和参数名都是相同的。
如果变量名称和参数名称不同,可以使用 name 属性配置 @RequestParam 名称:
@PostMapping("/api/foos") @ResponseBody public String addFoo(@RequestParam(name = "id") String fooId, @RequestParam String name) { return "ID: " + fooId + " Name: " + name; } 也可以使用 @RequestParam(value = "id") 或直接使用 @RequestParam("id")。
1、概览 本文将带你了解如何在 Spring 中重新加载 Properties 配置属性。
2、Spring 读取 Properties Spring 有几种不同的方式来访问 Properties:
Environment - 可以注入 Environment,然后使用 Environment#getProperty 来读取给定的属性。Environment 包含不同的属性源,如系统属性(System Properties)、-D 参数和 application.properties(或者 .yml) 等。还可以使用 @PropertySource 将额外的属性源添加到 Environment 中。 Properties - 可以将 properties 文件加载到 Properties 实例中,然后在 Bean 中通过调用 properties.get("property") 使用它。 @Value - 可以使用 @Value(${'property'}) 注解在 Bean 中注入特定属性。 @ConfigurationProperties - 可以使用 @ConfigurationProperties 在 Bean 中加载层次化的属性。。 3、重新加载外部属性文件 要在运行时更改文件中的属性(Properties),应该将该文件放在 Jar 之外的某个地方。然后使用命令行参数 -spring.config.location=file://{文件路径} 告诉 Spring 文件的位置。或者,也可以将其放在 application.properties 中。
对于基于磁盘文件的 Properties,可以开发一个端点或定时任务来读取文件并更新 Properties。
Apache 的 commons-configuration 是一个用于重新加载属性文件的库。可以使用 PropertiesConfiguration 和不同的 ReloadingStrategy 。
1、概览 本文将带你了解最常见的 Spring Bean 注解,用于定义不同类型的 Bean。
在 Spring 容器中配置 Bean 有几种方法。可以使用 XML 配置声明,也可以在配置类中使用 @Bean 注解声明 Bean。
最后,还可以使用 org.springframework.stereotype 包中的注解来标记类,然后由组件扫描来处理。
2、组件扫描 如果启用了组件扫描,Spring 就可以自动扫描包中的 Bean。
通过 @ComponentScan 注解配置要扫描的包,以查找带有注解配置的类。可以使用 basePackages 或 value 参数(value 是 basePackages 的别名)指定 base package:
@Configuration @ComponentScan(basePackages = "com.baeldung.annotations") class VehicleFactoryConfig {} 还可以使用 basePackageClasses 参数指定 base package 中的类:
@Configuration @ComponentScan(basePackageClasses = VehicleFactoryConfig.class) class VehicleFactoryConfig {} 这两个参数都是数组,因此可以为每个参数指定多个 package。
如果没有指定参数,将从 @ComponentScan 注解类所在的同一个包中开始扫描。
@ComponentScan 利用了 Java 8 的重复注解功能,这意味着可以多次使用它来标记一个类:
@Configuration @ComponentScan(basePackages = "com.baeldung.annotations") @ComponentScan(basePackageClasses = VehicleFactoryConfig.
1、简介 Spring Data 提供了对数据存储技术的抽象。因此,我们的业务逻辑代码可以更加独立于底层持久化实现。而且,Spring 还简化了处理与数据存储相关的实现细节的过程。
本文将带你了解 Spring Data、Spring Data JPA 和 Spring Data MongoDB 项目中最常见的注解。
2、常见的 Spring Data 注解 2.1、@Transactional @Transactional 用于定义事务方法:
@Transactional void pay() {} 如果在类上应用此注解,那么它就会对类中的所有方法起作用。也可以在方法上定义此注解来进行覆盖。
2.2、@NoRepositoryBean 有时我们会通过一个基本的 Repository 接口,定义一些通用的方法。然后,所有的 Repository 来继承这个基本的 Repository 接口。
基本的 Repository 接口不应该被实例化为 Bean,所以可以使用 @NoRepositoryBean 注解进行标注。
例如,如果想在所有 Repository 中使用 Optional<T> findById(ID id) 方法,那么可以创建一个基础 Repository 接口:
@NoRepositoryBean interface MyUtilityRepository<T, ID extends Serializable> extends CrudRepository<T, ID> { Optional<T> findById(ID id); } 此注解不会影响子接口,因此 Spring 将会把下面 Repository 接口创建为 Bean:
1、概览 本文将带你了解 org.springframework.scheduling.annotation 包中和调度相关的注解。
2、@EnableAsync 注解用于在 Spring 中启用异步功能。
必须与 @Configuration 一起使用:
@Configuration @EnableAsync class VehicleFactoryConfig {} 启用了异步调用后,可以使用 @Async 来定义支持异步调用的方法。
3、@EnableScheduling @EnableScheduling 用于启用定时任务调度。同样,必须与 @Configuration 结合使用:
@Configuration @EnableScheduling class VehicleFactoryConfig {} 启用了定时调度后,就可以可以使用 @Scheduled 注解来定期运行方法。
4、@Async @Async 用于注解需要异步执行的方法。
@Async void repairCar() { // ... } 如果将此注解应用于一个类,那么所有方法都将被异步调用。
注意,需要通过 @EnableAsync 或 XML 配置来启用异步调用,此注解才会生效。
5、@Scheduled 如果需要定期执行一个方法,可以使用此注解:
@Scheduled(fixedRate = 10000) void checkVehicle() { // ... } 可以使用它来按固定间隔执行方法,或者可以使用类似 cron 的表达式进行微调。
@Scheduled 利用了 Java 8 的重复注解功能,这意味着可以多次使用它来标记一个方法:
@Scheduled(fixedRate = 10000) @Scheduled(cron = "0 * * * * MON-FRI") void checkVehicle() { // .
1、概览 本文将带你了解 org.springframework.web.bind.annotation 包中的 Spring Web 注解。
2、@RequestMapping 简单地说,@RequestMapping 注解用于标记 @Controller 类中的请求处理方法(Handler),可配置的属性如下:
path 或其别名 name 和 value:方法映射到的 URL method:支持的 HTTP 方法 params:内容协商,根据 HTTP 参数的有无或值匹配请求 headers:内容协商,根据 HTTP Header 的存在、缺失或值匹配请求 consumes:支持的请求媒体类型(Content-Type) produces:响应的媒体类型 示例如下:
@Controller class VehicleController { @RequestMapping(value = "/vehicles/home", method = RequestMethod.GET) String home() { return "home"; } } 在 @Controller 类的类级应用此注解,就能为类中的所有 Handler 方法提供默认设置。唯一的例外是 URL,Spring 不会在方法级设置覆盖 URL,而是将两个 path 部分拼接在一起。
例如,以下配置与上述配置效果相同:
@Controller @RequestMapping(value = "/vehicles", method = RequestMethod.GET) class VehicleController { @RequestMapping("/home") String home() { return "home"; } } 此外,@GetMapping、@PostMapping、@PutMapping、@DeleteMapping 和 @PatchMapping 是 @RequestMapping 的不同变体,其 HTTP 方法已分别设置为 GET、POST、PUT、DELETE 和 PATCH。
1、概览 我们可以通过 org.springframework.beans.factory.annotation 和 org.springframework.context.annotation 包中的注解来使用 Spring DI 引擎的功能。
通常把这些注解称为 “Spring 核心注解”。
2、和 DI 相关的注解 2.1、@Autowired 可以在构造函数、Setter 方法或字段注入中使用 @Autowired 注解,Spring 会解析并注入依赖。
构造函数注入:
class Car { Engine engine; @Autowired Car(Engine engine) { this.engine = engine; } } Setter 注入:
class Car { Engine engine; @Autowired void setEngine(Engine engine) { this.engine = engine; } } 字段注入:
class Car { @Autowired Engine engine; } @Autowired 有一个名为 required 的 boolean 参数,默认值为 true。当 Spring 找不到合适的 Bean 进行注入时,它会控制 Spring 的行为。当值为 true 时,会抛出异常,反之则不会。
1、概览 本文将带你了解 Spring Kafka 中的 “Trusted Packages” 功能,了解其背后的动机以及用法。
2、先决条件 一般来说,Spring Kafka 模块允许我们指定一些关于发送的 POJO 的元数据。它通常采用 Kafka Message Header 的形式。
例如,可以这样配置 ProducerFactory:
@Bean public ProducerFactory<Object, SomeData> producerFactory() { JsonSerializer<SomeData> jsonSerializer = new JsonSerializer<>(); jsonSerializer.setAddTypeInfo(true); return new DefaultKafkaProducerFactory<>( producerFactoryConfig(), new StringOrBytesSerializer(), jsonSerializer ); } @Data @AllArgsConstructor static class SomeData { private String id; private String type; private String status; private Instant timestamp; } 然后,使用上面用 producerFactory 配置的 KafkaTemplate 在一个 Topic 中生产一条新消息:
public void sendDataIntoKafka() { SomeData someData = new SomeData("1", "active", "sent", Instant.
1、概览 本文将带你详细了解 Spring 中的 ApplicationContext 接口。
2、ApplicationContext 接口 Spring 框架的主要功能之一是 IoC(控制反转)容器。Spring IoC 容器负责管理应用的对象。它使用依赖注入来实现控制反转。
BeanFactory 和 ApplicationContext 接口,代表 Spring IoC 容器。其中,BeanFactory 是访问 Spring 容器的根接口。它提供了管理 Bean 的基本功能。
而 ApplicationContext 是 BeanFactory 的子接口。因此,它具备 BeanFactory 的所有功能。
此外,它还提供了更多面向企业的特定功能。ApplicationContext 的重要功能包括解析消息、支持国际化、发布事件以及应用层特定的上下文。这就是为什么我们将其作为默认的 Spring 容器使用的原因。
3、Spring Bean 是什么? 在深入了解 ApplicationContext 容器之前,有必要了解一下 Spring Bean。在 Spring 中,Bean 是 Spring 容器实例化、组装和管理的对象。
那么,是否应该将应用的所有对象都配置为 Spring Bean 呢?作为最佳实践,不应该这样做。
一般来说,根据 Spring 文档 所述,应该为服务层对象、数据访问对象 (DAO)、表现对象、基础架构对象(如 Hibernate SessionFactory、JMS Queue 等)定义 Bean。
此外,通常情况下,不应该在容器中配置细粒度的 Domain 对象。创建和加载 Domain 对象通常是 DAO 和业务逻辑的职责。