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 和业务逻辑的职责。
1、概览 通过 Cron 表达式,我们可以安排任务在特定日期和时间定期运行。Cron 表达式在 Unix 中推出后,其他基于 Unix 的操作系统和软件库(包括 Spring)都采用了它的任务调度方法。
本文将带你了解基于 Unix 操作系统的 Cron 表达式与 Spring Cron 之间的区别。
2、Unix Cron 在大多数基于 Unix 的系统中,Cron 有五个字段:分钟(0-59)、小时(0-23)、月日(1-31)、月份(1-12 或名称)和星期(0-7 或名称)。
可以在每个字段中添加一些特殊值,如星号(*):
5 0 * * * 任务将在每天午夜后 5 分钟执行。也可以使用数值范围:
5 0-5 * * * 如上,调度器将在午夜 12 点后 5 分钟执行任务,并在每天 1 点、2 点、3 点、4 点和 5 点后 5 分钟执行任务。
或者,可以使用一个值列表:
5 0,3 * * * 现在,调度器会在每天午夜 12 点后 5 分钟和下午 3 点后 5 分钟执行作业。原始 Cron 表达式提供的功能远不止这些。
1、概览 使用 Spring 的 @PathVariable 和 @RequestMapping 来映射包含点的请求时,最后一个 URI 路径变量的值被会截断。
2、原因 具体来说,Spring 认为最后一个点后面的任何内容都是文件扩展名,如 .json 或 .xml,因此,它会截断值以检索路径变量。
来看一个使用路径变量的例子:
@RestController public class CustomController { @GetMapping("/example/{firstValue}/{secondValue}") public void example(@PathVariable("firstValue") String firstValue, @PathVariable("secondValue") String secondValue) { // ... } } 如上,考虑以下请求 URL 以及 firstValue 和 secondValue 变量的值:
example/gallery/link:firstValue = "gallery",secondValue = "link"。 example/gallery.df/link.ar URL:firstValue = "gallery.df ",secondValue = "link" example/gallery.df/link.com.ar:firstValue = "gallery.df",secondValue = "link.com" 可以看到,第一个变量不受影响,但第二个带点(.)的变量总是被截断。
3、解决办法 解决这种不便的方法之一是修改 @PathVariable 定义,添加一个 regex(正则)映射。这样,任何点(包括最后一个点)都将被视为参数的一部分:
@GetMapping("/example/{firstValue}/{secondValue:.+}") public void example( @PathVariable("firstValue") String firstValue, @PathVariable("secondValue") String secondValue) { //.
1、概览 本文将带你了解 Spring 中 @PathVariable 注解的作用和用法。
简单地说,@PathVariable 注解可用于处理请求 URI 映射中的模板变量,并将其绑定到 Controller 方法参数。
2、示例映射 @PathVariable 注解的一个简单用例是用于标识具有 ID 的实体的端点:
@GetMapping("/api/employees/{id}") @ResponseBody public String getEmployeesById(@PathVariable String id) { return "ID: " + id; } 在本例中,使用 @PathVariable 注解来提取 URI 的模板部分,该部分由变量 {id} 表示。
调用示例如下:
http://localhost:8080/api/employees/111 ---- ID: 111 3、指定 PATH (路径)变量名 在上一个示例中,由于方法参数和路径变量的名称相同,可以不用主动设置模板路径变量的名称。
如果路径变量名不同,可以在 @PathVariable 注解的参数中指定:
@GetMapping("/api/employeeswithvariable/{id}") @ResponseBody public String getEmployeesByIdWithVariableName(@PathVariable("id") String employeeId) { return "ID: " + employeeId; } 测试如下:
http://localhost:8080/api/employeeswithvariable/1 ---- ID: 1 为了清晰起见,还可以将路径变量名定义为 @PathVariable(value="id"),而不是 PathVariable("id")。
1、概览 本文将带你了解 Spring Async 和 Spring WebFlux 之间的区别。
2、场景 本文分别用 Spring Async 和 Spring WebFlux 来实现一个简单的 Web 应用。
Web 请求会通过一个延迟时间为 200 毫秒的 Filter,然后 Controller 需要 500 毫秒来计算并返回结果。
最后使用 Apache ab 分别进行负载测试,并使用 JConsole 监控应用的行为。
3、Spring MVC Async Spring 3.0 引入了 @Async 注解。@Async 的目标是允许应用在单独的线程上运行重负载的任务。此外,调用方可以等待结果(如果感兴趣)。因此,返回类型不能是void,而可以是 Future、CompletableFuture 或 ListenableFuture 之一。
Spring 3.2 引入了 org.springframework.web.context.request.async 包,它与 Servlet 3.0 一起为 Web 层带来了异步的支持。因此,自 Spring 3.2 起,@Async 可以在 @Controller 或 @RestController 类中使用。
当客户端发起请求时,请求会经过过滤器链(filter chain)中所有匹配的过滤器(filter),直到到达 DispatcherServlet 实例。
然后,Servlet 会对请求进行异步调度。它通过调用 AsyncWebRequest#startAsync 将请求标记为已启动,将请求处理转移到 WebSyncManager 的实例,然后在不提交响应的情况下完成其工作。过滤器链也按相反的方向遍历执行到根节点。