Spring 是一个流行的 Java 开发框架,提供了大量的注解来实现依赖注入和面向切面编程等功能。以下是一些常用的 Spring 注解:
文章目录
- 1. @Async:将方法标注为异步执行。
- 2. @Autowired:自动装配依赖的 bean。
- 3. @Bean:声明一个需要被 Spring 管理的 bean。
- 4. @Cacheable:增加缓存支持。
- 5. @ComponentScan:指示 Spring 扫描和发现指定包及其子包中的组件类并自动注册为 Spring Beans。
- 6. @Conditional:给一个配置类或者方法分别添加不同的条件。
- 7. @Configuration:声明一个类作为配置文件。
- 8. @ConstructorBinding:表示绑定到类构造函数上。
- 9. @Controller:声明一个控制器类,用于处理 HTTP 请求。
- 10. @ControllerAdvice:在全局范围内使用的控制器建议类。
- 11. @CrossOrigin:开启跨域支持。
- 12. @DeleteMapping:处理 HTTP DELETE 请求。
- 13. @DependsOn:指定 bean 之间的依赖关系。
- 14. @EnableAsync:启用异步执行支持。
- 15. @EnableScheduling:启用计划任务支持。
- 16. @ExceptionHandler:定义全局的异常处理器。
- 17. @GetMapping:处理 HTTP GET 请求。
- 18. @Import:导入其他配置类。
- 19. @ImportResource:导入 XML 配置文件。
- 20. @ImportSelector:提供了一个特殊的接口,以允许选择要导入的项目。
- 21. @InitBinder:用于初始化数据绑定器。
- 22. @Lazy:标记 bean 为懒加载。
- 23. @MetaAnnotation:定义元注解,即可用于自定义注解上的注解。
- 24. @ModelAttribute:方法参数注解,用于从请求对象中填充 POJO 对象的属性值。
- 25. @Order:指示组件应在其所有注入器已装配完成后被排序。
- 26. @PostMapping:处理 HTTP POST 请求。
- 27. @Primary:注释为默认首选 bean。
- 28. @Profile:确定配置在特定情况或环境下使用的 bean。
- 29. @PropertySource:加载外部属性文件以替换当前环境中的占位符。
- 30. @Qualifier:使用合格名选择 Bean。
- 31. @RequestMapping:将 HTTP Request 映射到处理程序方法。
- 32. @Repository:声明一个类作为数据访问对象(DAO)的类。
- 33. @RequestHeader:获取请求头中指定名称的值。
- 34. @RequestParam:从请求参数中获取值。
- 35. @RequestBody:从请求体中获取值。
- 36. @ResponseStatus:指示 Spring 处理程序方法的 HTTP 响应状态。
- 37. @Resource:通常作为 JNDI 的替代方案来注入类、属性或方法。
- 38. @Scheduled:用于创建调度任务。
- 39. @Scope:标识 bean 的作用域。
- 40. @Service:声明一个类作为服务类。
- 41. @SessionAttributes:指定会话属性。
- 42. @Transactional:启用事务管理。
- 43. @Validated:用于方法参数验证。
- 44. @PatchMapping:处理 HTTP PATCH 请求。
- 45. @PathVariable:从请求 URI 模板中获取值。
- 46. @PutMapping:处理 HTTP PUT 请求。
- 47. @TransactionalEventListener:声明一个异步的事务事件监听器。
- 48. @Value:注入外部属性值。
- 49. @ValueConstants:标识注解的常量值。
- 50. @Valid:用于方法参数验证。
1. @Async:将方法标注为异步执行。
@Async 注解是 Spring Framework 提供的基于注解的异步执行方法的功能。将这个注解放在一个方法上时,该方法会在一个新线程中异步执行,而不会阻塞当前线程。
这个注解一般用于需要长时间执行或者阻塞操作的方法,例如发送大量邮件或者需要耗费很长时间才能返回结果的计算等。使用 @Async 注解可以提高应用程序的并发性和响应速度,同时也可以避免因为一个方法的返回值导致整个应用程序阻塞的情况。
需要注意的是,使用 @Async 注解的方法必须由 Spring 框架装配,因为在异步方式下,直接调用这些方法的代码可能无法获取到异步执行结果。如果您在一个普通的方法或者类中调用了由 @Async 注解标记的方法,那么当前线程会立即返回,而实际执行的过程会在另外的线程中进行,当前线程将继续执行自身的任务。
同时,@Async 注解还需要通过配置文件来开启异步支持。例如,在 Spring Boot 应用程序中,我们可以把 @EnableAsync 注解放在配置类上来启用异步支持。
以下是一个使用 @Async 注解的示例:
@Service
public class MyService {
@Autowired
private EmailService emailService;
@Async
public void sendEmails(List<String> recipients, String content) {
for (String recipient : recipients) {
emailService.sendEmail(recipient, content);
}
System.out.println("All emails sent!");
}
}
在上面的代码中,我们定义了一个异步方法 sendEmails
用于向一组邮件收件人发送电子邮件。这个方法接收两个参数,一个是所有收件人的列表,另一个是电子邮件的内容。
在方法执行过程中,我们通过遍历收件人列表调用 emailService
发送邮件。由于 sendEmail
方法可能会阻塞当前线程,我们使用 @Async 注解标明该方法需要在新的线程中异步执行,这样方法调用会立即返回而不会阻塞当前线程。当所有邮件都成功发送后,控制台将打印出 “All emails sent!” 的字样。
需要注意的是,在上面的示例代码中,我们需要确保 Spring 容器中已经装配了 EmailService
实例,否则会引发运行时异常。同时,在应用程序的配置文件中,我们还需要启用异步支持才能正常使用 @Async 注解。
2. @Autowired:自动装配依赖的 bean。
@Autowired 注解是 Spring Framework 中的一个依赖注入注解,它可以自动将容器中已经创建好的 bean 对象装配到需要他们的类或者方法中。
Autowired 能够根据类型自动装配,如果容器中有多个同类型的 bean,则可以通过 @Qualifier 注解指定唯一的 bean 名称进行注入。同时,Autowired 也提供了 required 属性,用于定义依赖项是否必须注入成功。
以下是一个使用 @Autowired 注解的示例:
@Service
public class MyService {
@Autowired
private UserDao userDao;
public void saveUser(User user) {
userDao.save(user);
}
}
在上面的代码中,我们定义了一个服务类 MyService
,并将 UserDao
对象自动注入到该类中。这个注入的过程是由 Spring 容器完成的,因此能够确保对象的正确性和生命周期管理。
需要注意的是,使用 @Autowired 注解需要开启自动扫描和组件装配功能,因此需要在 Spring 的配置文件中启用相关配置。例如,在 Spring Boot 应用程序中,我们可以把 @SpringBootApplication 注解放在启动类上,这会自动开启组件扫描和自动装配功能。
另外,在 Spring 5.0 版本之后,@Autowired 注解还支持构造函数注入、setter 注入和字段注入三种方式。具体使用哪种方式注入可以根据具体情况选择。
3. @Bean:声明一个需要被 Spring 管理的 bean。
@Bean 注解是 Spring Framework 中的一个注解,用于定义 bean 对象,并提供了一种便捷的方式将其注册到 Spring 容器中。
以下是一个使用 @Bean 注解的示例:
@Configuration
public class MyConfiguration {
@Bean
public UserDao userDao() {
return new JdbcUserDao(dataSource());
}
@Bean
public DataSource dataSource() {
// 创建并配置数据源对象
return new HikariDataSource(config);
}
}
在上面的代码中,我们定义了一个配置类 MyConfiguration
,并在其中定义了两个 bean 对象:userDao()
和 dataSource()
。其中 userDao()
方法返回 JdbcUserDao
对象,而 dataSource()
方法返回一个 Hikari 数据源对象。这两个方法都标记了 @Bean 注解,这意味着它们会被 Spring 容器扫描到并将创建的对象注册到容器中。
需要注意的是,在上面的示例中,我们还添加了 @Configuration 注解来标识这是一个配置类,因此 Spring 容器在扫描时会识别并加载该类。
@Bean 注解还支持指定特定名称的 bean 对象,例如:@Bean(“myBean”),这样可以在装配其他依赖项时方便地引用该 bean 对象。
同时,@Bean 注解也支持传递参数和依赖注入,如下所示:
@Configuration
public class MyConfiguration {
@Bean
public FooService fooService(BarService barService) {
return new FooServiceImpl(barService);
}
@Bean
public BarService barService() {
return new BarServiceImpl();
}
}
在上面的代码中,我们定义了 FooService
和 BarService
两个 bean,但是 FooService
需要依赖 BarService
。因此,在创建 fooService()
方法时,我们使用 barService()
方法获取到已经存在的 BarService
实例,并将其传递给 FooServiceImpl
的构造函数。
这样,当 fooService()
方法被调用时,Spring 容器会自动解析 barService()
的服务实例,并传入到 FooServiceImpl
的构造函数中,完成依赖注入的过程。
4. @Cacheable:增加缓存支持。
@Cacheable 是 Spring Framework 中的一个注解,用于实现方法级别的缓存。使用 @Cacheable 注解的方法在调用时,将会检查缓存中是否存在与该方法所需参数相对应的缓存项。如果存在,则直接返回缓存结果,不再执行被注解的方法;如果不存在,则执行该方法,并将方法的返回结果添加到缓存中。
以下是一个使用 @Cacheable 注解的示例:
@Service
public class UserService {
private final UserMapper userMapper;
public UserService(UserMapper userMapper) {
this.userMapper = userMapper;
}
@Cacheable(value = "users", key = "#userId")
public User getUserById(int userId) {
return userMapper.getUserById(userId);
}
}
在上面的代码中,我们定义了一个 UserService 类,其中包含一个 getUserById()
方法,该方法使用 @Cacheable 注解进行标记。value 属性指定了缓存名称为 “users”,key 属性则指定了缓存项的键值为传入的 userId 参数。
当这个方法被调用时,Spring 将首先检查缓存中是否已经存在以传入的 userId 作为键值保存的缓存项。如果有,则直接从缓存中获取结果并返回;如果没有,则执行方法逻辑,获得返回值,并将返回值以 userId 为键值保存到缓存中,以备下次调用时直接返回。
需要注意的是,@Cacheable 注解通常和其他缓存相关的注解组合使用,如 @CacheConfig、@CachePut 和 @CacheEvict 等。同时,Spring 还支持多种缓存技术的实现,由用户自行选择适合的方案进行配置。
5. @ComponentScan:指示 Spring 扫描和发现指定包及其子包中的组件类并自动注册为 Spring Beans。
@ComponentScan 是 Spring Framework 中的一个注解,用于指定要扫描的包及其子包中标记有 @Component 及其派生注解标记的 Bean,并将其注册到 Spring 容器中。
以下是一个使用 @ComponentScan 注解的示例:
@Configuration
@ComponentScan(basePackages = {"com.example.service", "com.example.repository"})
public class MyConfiguration {
}
在上面的代码中,我们定义了一个名为 MyConfiguration 的配置类,并标记了 @Configuration 和 @ComponentScan 两个注解。其中,@ComponentScan 注解指定了需要扫描的包路径为 com.example.service 和 com.example.repository,这两个包及其子包中所有标注了 @Component 及其派生注解的 Bean 都会被扫描到,并自动注册到 Spring 容器中。
在实际应用中,@ComponentScan 注解通常和其他注解一起使用,以完成更加复杂的业务逻辑。
需要注意的是,默认情况下,@ComponentScan 注解会搜索当前类所在包及其子包下所有的组件。可以通过额外的参数属性来调整其行为方式,例如:
- basePackageClasses:指定被扫描的启动类所在的包路径。
- excludeFilters:指定不需要被扫描的类或者包。
- includeFilters:指定只需要被扫描的类或者包。
同时,@ComponentScan 还支持其他可选参数,具体可参考 Spring 官方文档。
6. @Conditional:给一个配置类或者方法分别添加不同的条件。
@Conditional 是 Spring Framework 中的一个注解,用于根据特定条件动态决定是否创建某个 Bean 实例。
以下是一个使用 @Conditional 注解的示例:
@Configuration
public class MyConfiguration {
@Bean
@Conditional(MyCondition.class)
public MyBean myBean() {
return new MyBean();
}
}
在上面的代码中,我们定义了一个名为 MyConfiguration 的配置类,并标记了 @Configuration 注解。同时,我们又通过 @Bean 注解将一个名为 myBean 的 Bean 注册到容器中,在方法上添加了 @Conditional(MyCondition.class) 注解来限制创建 Bean 的条件。
这里我们自定义了一个名为 MyCondition 的条件类,具体实现如下:
public class MyCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// TODO: 自定义条件判断逻辑
return true;
}
}
MyCondition 接口实现了 Spring 框架提供的 Condition
接口,它有一个名为 matches 的方法,该方法返回一个布尔值,指示是否符合条件。
matches 方法中可以编写自定义的判断逻辑,当结果为 true 时,表示条件成立,按照要求创建 Bean;否则,则不会创建这个 Bean。
需要注意的是,@Conditional 注解通常和其他注解一起使用,以完成更加复杂的业务逻辑。
同时,Spring 还提供了一些预定义的条件注解,如 @Profile、@ConditionalOnMissingClass、@ConditionalOnProperty 等,它们可以方便地满足一些常见的判断场景,减少了编写自定义条件类的工作量。
7. @Configuration:声明一个类作为配置文件。
@Configuration 是 Spring Framework 中的一个注解,用于将类标记为配置类。配置类一般用来定义 Bean 的创建、配置和组装过程,并返回这些 Bean 实例供应用程序使用。
以下是一个使用 @Configuration 注解的示例:
@Configuration
public class MyConfiguration {
@Bean
public MyBean myBean() {
return new MyBean();
}
}
在上面的代码中,我们定义了一个名为 MyConfiguration 的配置类,并标记了 @Configuration 注解。随后,我们又通过 @Bean 注解将一个名为 myBean 的 Bean 注册到容器中。
MyBean 是一个普通的 Java 类,Spring 容器将根据其类型创建一个实例,并将其注册到容器中,以供后续的程序调用。
需要注意的是,在使用 @Configuration 进行配置时,通常会配合其他注解进行使用,如:@ComponentScan、@Import、@Value 等。
总之,@Configuration 注解的作用是告诉 Spring,这个类是一个配置类,其中包含了一些 Bean 的定义和组装逻辑。当 Spring 启动时,会自动扫描这个配置类,并将其中的 Bean 注册到容器中,以供其他组件使用。
8. @ConstructorBinding:表示绑定到类构造函数上。
@ConstructorBinding 是 Spring Boot 2.2 中引入的一个注解,用于标记不可变类型(immutable)的构造器参数,通过将构造器参数绑定到属性中从而完成自动配置。
以下是一个使用 @ConstructorBinding 注解的例子:
@ConfigurationProperties(prefix = "myconfig")
@ConstructorBinding
public class MyConfigProps {
private final String username;
private final String password;
public MyConfigProps(String username, String password) {
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
}
在上面的代码中,我们定义了一个名为 MyConfigProps 的 POJO 类,并使用 @ConstructorBinding 注解标注了类。同时,我们又通过 @ConfigurationProperties 注解指定了属性文件的前缀,以及要绑定的属性值。
MyConfigProps 中的构造函数使用了两个 final 修饰的参数,表示这些参数是不可变的。在实例化 MyConfigProps 对象时,构造函数会被调用,并将 prefix + “.username” 和 prefix + “.password” 从属性文件中绑定到实例对象中。
需要注意的是,当使用 @ConstructorBinding 标记类时,必须保证该类的所有构造函数都是 immutable 的,即所有参数必须使用 final 修饰符来标明其只读性,防止意外修改对象状态。
总之,@ConstructorBinding 注解使得 Spring Boot 更容易地支持自动配置不可变类型的 Bean,提升了程序的安全性和可维护性。
9. @Controller:声明一个控制器类,用于处理 HTTP 请求。
@Controller 是 Spring MVC 框架中的一个注解,用于将带有请求处理器方法的类标识为控制器。
以下是一个使用 @Controller 注解的例子:
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public String getUser(@PathVariable("id") Long id, Model model) {
User user = userService.getUserById(id);
model.addAttribute("user", user);
return "user";
}
@PostMapping("/")
public String addUser(UserDTO userDTO) {
User user = userService.addUser(userDTO);
return "redirect:/user/" + user.getId();
}
}
在上面的代码中,我们定义了一个名为 UserController 的控制器,并标记了 @Controller 注解。同时,我们又使用了 @RequestMapping 注解指定了该控制器的根路径为 “/user”。
在 UserController 中,我们定义了两个请求处理器方法:getUser() 和 addUser()。通过使用 @GetMapping 和 @PostMapping 注解标记不同的 HTTP 动作和 URL 映射,让 Spring MVC 框架能够自动处理这些请求。
需要注意的是,Controller 通常会依赖其他 Bean 来完成业务逻辑的处理,在上述示例中我们使用了 @Autowired 标记来注入 UserService,从而实现对 User 对象的添加和查询等操作。
总之,@Controller 注解是 Spring MVC 框架中用于标记控制器类的注解。通过在控制器类中定义请求处理方法,可以处理来自用户端的请求,并将响应返回给客户端。
10. @ControllerAdvice:在全局范围内使用的控制器建议类。
@ControllerAdvice 是 Spring MVC 框架中的注解,用于定义一个全局性的异常处理器类。可以对 Controller 层面和全局异常进行统一的处理。
以下是一个使用 @ControllerAdvice 注解的例子:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler({NullPointerException.class, IllegalArgumentException.class})
public String handleException(Exception e, HttpServletRequest request) {
request.setAttribute("error", e);
return "error";
}
}
在上面的代码中,我们定义了一个名为 GlobalExceptionHandler 的类,并标记了 @ControllerAdvice 注解。同时,我们又通过 @ExceptionHandler 注解声明了一个处理异常的方法,当捕获到空指针异常或者非法参数异常时,会执行这个方法,将异常信息添加到 request 中,并返回 “error” 视图。
需要注意的是,@ControllerAdvice 注解通常和 @ExceptionHandler 注解一起使用,配合使用时,@ExceptionHandler 可以定义多个处理特定异常类型的方法,不同异常类型对应不同的处理逻辑,这样遇到异常就可根据异常类型选用相应的处理方法进行处理。
总之,@ControllerAdvice 注解可以在应用程序全局范围内共享有关异常处理的行为,可以实现更加细粒度、灵活化的异常处理方式,增强了应用的健壮性和容错性。
11. @CrossOrigin:开启跨域支持。
@CrossOrigin 是 Spring MVC 框架中的注解,用于解决跨域资源共享问题。可以让某个特定的 Controller 放行一些指定来源的请求。
以下是一个使用 @CrossOrigin 注解的例子:
@RestController
@RequestMapping("/api")
public class ApiController {
@CrossOrigin(origins = "http://localhost:8080")
@GetMapping("/users/{id}")
public User getUserById(@PathVariable Long id) {
// ...
}
}
在上面的代码中,我们定义了一个名为 ApiController 的控制器,并标记了 @RestController 和 @RequestMapping 注解。同时,我们又通过 @CrossOrigin 注解声明了允许来自 http://localhost:8080 地址的跨域请求。在该控制器中的 getUserById() 方法能够处理 GET 请求 /api/users/{id},并返回与用户 ID 相对应的用户信息。
需要注意的是,@CrossOrigin 注解可以定义多个参数,例如 allowCredentials、allowedHeaders 等。其中,allowCredentials 值为 true 时表示允许服务器端发送 cookies;allowedHeaders 用于配置 CORS 请求中允许出现的自定义 header,这样能够避免浏览器的预检 OPTIONS 请求延迟。
总之,@CrossOrigin 注解是 Spring MVC 框架中用于处理跨域资源共享的注解。它使得在开发中实现异构协议通信变得容易,主要用于前后端分离开发场景下的服务端配置。
12. @DeleteMapping:处理 HTTP DELETE 请求。
@DeleteMapping 是 Spring MVC 框架中的注解,用于告诉服务器需要删除一个特定的资源。它表示处理 HTTP DELETE 方法的方法级注解。
以下是一个使用 @DeleteMapping 注解的例子:
@RestController
@RequestMapping("/api")
public class ApiController {
@DeleteMapping("/users/{id}")
public void deleteUserById(@PathVariable Long id) {
// 删除用户 ID 对应的用户信息
}
}
在上面的代码中,我们定义了一个名为 ApiController 的控制器,并标记了 @RestController 和 @RequestMapping 注解。同时,我们又通过 @DeleteMapping 注解声明了允许处理 DELETE 请求 /api/users/{id},并且所删除的资源对应着传入的用户 ID。
需要注意的是,与其他类型的请求方式相同,@DeleteMapping 也可以接受一些参数值,例如 consumes、produces 等。其中,consumes 声明实体的 MIME 类型,例如 application/json、application/xml 等;produces 表示响应中将包含的 MINE 类型。
总之,@DeleteMapping 注解是 Spring MVC 框架中用于处理 HTTP DELETE 方法的方法属性注解。它可以很方便地配置服务器端的资源删除操作,是 RESTful 风格 API 开发中常用的组成部分。
13. @DependsOn:指定 bean 之间的依赖关系。
@DependsOn 是 Spring 框架中的注解,用于指定当前 Bean 依赖于另一个 Bean。当 Spring IOC 容器初始化时,会首先初始化所依赖的 Bean,确保它们可用后才会开始初始化当前的 Bean。
以下是一个使用 @DependsOn 注解的例子:
@Component
@DependsOn("dataSource")
public class DataInitializer {
@Autowired
private JdbcTemplate jdbcTemplate;
public void initData() {
// 使用 jdbcTemplate 初始化数据
}
}
在上面的代码中,我们定义了一个名为 DataInitializer 的组件,并标记了 @Component 注解。同时,又通过 @DependsOn 注解声明了该组件依赖于 “dataSource” Bean。这样,在容器初始化时,Spring 会先初始化 dataSource Bean,确保它可用之后再初始化 DataInitializer 组件。
需要注意的是,@DependsOn 注解可以接收多个字符串值,以逗号分隔。
总之,@DependsOn 注解可以用于控制 Bean 的初始化顺序,确保某些 Bean 可用后再实例化其他 Bean。它对于那些有依赖关系的 Bean 组合而言非常有用,可以避免一些已知的依赖性问题。
14. @EnableAsync:启用异步执行支持。
@EnableAsync 是 Spring 框架中的注解,用于启用异步方法调用。在应用程序中,有时需要执行一些时间较长的操作,例如发送邮件、文件上传等,这些操作通常需要花费相当长的时间。如果我们在处理这些操作时使用同步方式进行处理,则会对 Web 应用程序的性能产生负面影响,因此可以考虑使用异步方法。
以下是一个使用 @EnableAsync 注解的例子:
@Configuration
@EnableAsync
public class AppConfig {
@Bean
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(30);
executor.initialize();
return executor;
}
}
在上面的代码中,我们首先定义了一个名为 taskExecutor 的 Bean(线程池),并配置了它的核心线程数、最大线程数和队列容量。接着,通过 @EnableAsync 注解,启用了 Spring 的异步方法,并指定任务的执行器为上述 taskExecutor。
需要注意的是,@EnableAsync 注解需要与异步方法搭配使用,异步方法需要用 @Async 标记。
总之,@EnableAsync 注解是 Spring 框架中用于启用异步方法调用的注解。它可以帮助我们提高应用程序性能,尤其是在处理一些 IO 密集型操作时,非常有用。
15. @EnableScheduling:启用计划任务支持。
@EnableScheduling 是 Spring 框架中的注解,用于启用定时任务。在实际开发中,有许多需要定时执行的任务,例如定时备份、定时邮件通知等,这些任务可以使用 Spring 的集成定时任务框架来实现。
以下是一个使用 @EnableScheduling 注解的例子:
@Configuration
@EnableScheduling
public class AppConfig {
// 其他组件的定义...
@Scheduled(cron = "0 0 0 * * ?")
public void backupDatabase() {
// 实现数据库备份逻辑...
}
}
在上面的代码中,我们在 AppConfig 类上标记了 @EnableScheduling 注解,以启用 Spring 的定时任务功能。接着,我们定义了一个名为 backupDatabase 的方法,并通过 @Scheduled 注解指定了它的调用时间 - 每天凌晨 0 点。
需要注意的是,@Scheduled 注解常用的定时任务调度表达式有三种:cron 表达式、fixedDelay 和 fixedRate。
总之,@EnableScheduling 注解是 Spring 中用于启用定时任务的注解,它可以帮助我们方便地实现各种定时任务。同时,Spring 提供了丰富的定时任务调度表达式,可以满足各种任务需求,非常强大和灵活。
16. @ExceptionHandler:定义全局的异常处理器。
@EnableScheduling 是 Spring 框架中的注解,用于启用定时任务。在实际开发中,有许多需要定时执行的任务,例如定时备份、定时邮件通知等,这些任务可以使用 Spring 的集成定时任务框架来实现。
以下是一个使用 @EnableScheduling 注解的例子:
@Configuration
@EnableScheduling
public class AppConfig {
// 其他组件的定义...
@Scheduled(cron = "0 0 0 * * ?")
public void backupDatabase() {
// 实现数据库备份逻辑...
}
}
在上面的代码中,我们在 AppConfig 类上标记了 @EnableScheduling 注解,以启用 Spring 的定时任务功能。接着,我们定义了一个名为 backupDatabase 的方法,并通过 @Scheduled 注解指定了它的调用时间 - 每天凌晨 0 点。
需要注意的是,@Scheduled 注解常用的定时任务调度表达式有三种:cron 表达式、fixedDelay 和 fixedRate。
总之,@EnableScheduling 注解是 Spring 中用于启用定时任务的注解,它可以帮助我们方便地实现各种定时任务。同时,Spring 提供了丰富的定时任务调度表达式,可以满足各种任务需求,非常强大和灵活。
17. @GetMapping:处理 HTTP GET 请求。
@GetMapping 是 Spring 框架中的注解之一,它表示一个 HTTP GET 请求方法。使用 @GetMapping 注解可以将一个方法映射到指定的 URL 上,并指定 HTTP 请求的方法为 GET。
以下是一个使用 @GetMapping 注解的例子:
@RestController
@RequestMapping("/api")
public class UserController {
@GetMapping("/users/{id}")
public User getUserById(@PathVariable("id") Long id) {
// 根据 id 查询用户...
}
}
在上面的代码中,我们首先使用 @RestController 和 @RequestMapping 注解标记了 UserController 类,并将请求路径设置为 /api。然后,我们使用 @GetMapping 注解将 getUserById 方法映射到 /users/{id} URL 上,并指定了一个路径变量 id,用于获取用户 ID。
除了 @GetMapping 之外,Spring 还提供了其他 HTTP 请求方法的注解,例如 @PostMapping、@PutMapping 和 @DeleteMapping 等等,它们都遵循相同的规则和使用方式。
总之,@GetMapping 注解用于将一个方法映射到 HTTP GET 请求上,它可以帮助我们轻松实现 RESTful 风格的 API 接口,非常方便和易用。
18. @Import:导入其他配置类。
@Import 是 Spring 框架中的注解之一,它允许我们在一个配置类中引入其他配置类或普通的 Java 类。使用 @Import 注解可以将指定的类或类数组(声明为 value 属性)加载到当前的 Spring ApplicationContext 中,从而将它们注册为 Spring 的 bean。
以下是一个使用 @Import 注解的例子:
@Configuration
@Import({DataSourceConfig.class, RedisConfig.class})
public class AppConfig {
// ...
}
在上面的代码中,我们定义了一个名为 AppConfig 的配置类,并使用 @Import 注解引入了另外两个配置类:DataSourceConfig 和 RedisConfig。这样一来,在创建 Spring ApplicationContext 时,这三个配置类都会被加载并注册为 Spring 的 bean。
需要注意的是,@Import 注解除了可以引入其他的配置类外,还可用于引入普通的 Java 类,例如:
@Configuration
@Import(ServiceUtils.class)
public class AppConfig {
// ...
}
在上面的代码中,我们将一个名为 ServiceUtils 的普通 Java 类导入了 AppConfig 中,这样就可以在 AppConfig 中使用 ServiceUtils 类中的方法或属性了。
总之,@Import 注解允许我们在一个配置类中引入其他配置类或普通的 Java 类,以便共享配置信息和 bean 定义,非常灵活和方便,是 Spring 配置文件编写的常用技巧之一。
19. @ImportResource:导入 XML 配置文件。
@ImportResource 是 Spring 框架中的注解之一,它允许我们通过 XML 文件方式导入配置信息和 bean 定义。使用 @ImportResource 注解可以将一个或多个 XML 文件加载到当前的 Spring ApplicationContext 中,并将其中定义的 bean 注册为 Spring 的 bean。
以下是一个使用 @ImportResource 注解的例子:
@Configuration
@ImportResource("classpath:applicationContext.xml")
public class AppConfig {
// ...
}
在上面的代码中,我们定义了一个名为 AppConfig 的配置类,并使用 @ImportResource 注解引入了一个叫做 applicationContext.xml 的XML 配置文件。这样一来,在创建 Spring ApplicationContext 时,该XML 配置文件中定义的 bean 就会被加载并注册为 Spring 的 bean。
需要注意的是,@ImportResource 注解也可以引入多个 XML 配置文件,例如:
@Configuration
@ImportResource({"classpath:applicationContext1.xml", "classpath:applicationContext2.xml"})
public class AppConfig {
// ...
}
在上面的代码中,我们将两个 XML 配置文件都导入了 AppConfig 中。
总之,@ImportResource 注解允许我们通过 XML 文件方式导入配置信息和 bean 定义,与纯 JavaConfig 形式相比,更加灵活,方便维护复杂配置信息。但是,由于 XML 配置方式易出错,建议尽量避免使用过度的 XML 配置。
20. @ImportSelector:提供了一个特殊的接口,以允许选择要导入的项目。
@ImportSelector 是 Spring 框架中的注解之一,它允许我们编写自定义类,以动态地选择和返回多个要导入到当前 Spring 容器中的配置类。使用 @ImportSelector 注解需要实现 ImportSelector 接口。
以下是一个使用 @ImportSelector 注解的例子:
@Configuration
@Import(MyImportSelector.class)
public class AppConfig {
// ...
}
在上面的代码中,我们定义了一个名为 AppConfig 的配置类,并使用 @Import 注解引入了一个叫做 MyImportSelector 的 ImportSelector 实现类。根据具体需要,MyImportSelector 类可以按照某种条件或算法,动态地返回一个或多个要导入到当前 Spring 容器中的配置类。
要完整地使用 @ImportSelector 注解,我们还需要定义一个 ImportSelector 实现类,例如:
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
// 根据具体需要,编写动态返回配置类的逻辑
return new String[]{"com.example.demo.config.DataSourceConfig", "com.example.demo.config.RedisConfig"};
}
}
在上面的代码中,MyImportSelector 类实现了 ImportSelector 接口,并重写了 selectImports() 方法,根据具体需要返回需要导入到 Spring 容器中的配置类。在本例中,MyImportSelector 返回了 DataSourceConfig 和 RedisConfig 配置类。
总之,@ImportSelector 注解允许我们编写自定义类,以动态地选择和返回多个要导入到当前 Spring 容器中的配置类。它可以极大地提高配置类的灵活性和可复用性,但是需要对 Spring 框架比较熟悉才能正确使用。
21. @InitBinder:用于初始化数据绑定器。
@InitBinder 是 Spring MVC 框架中的注解之一,它用于将公共数据绑定到 WebDataBinder 对象中。WebDataBinder 对象是 Spring MVC 框架中的一个重要对象,负责将表单数据绑定到 JavaBean 上。
当我们在控制器类中定义了一个带有 @InitBinder 注解的方法时,这个方法会在每个请求处理方法执行前执行,用于初始化 WebDataBinder 对象并进行一些自定义设置操作,例如增加一个全局日期格式化器、禁用某些参数的绑定等。
以下是一个使用 @InitBinder 注解的例子:
@ControllerAdvice
public class GlobalControllerAdvice {
@InitBinder
public void initBinder(WebDataBinder binder) {
// 添加全局日期格式化器
binder.addCustomFormatter(new DateFormatter("yyyy-MM-dd HH:mm:ss"));
// 禁止 id 参数绑定,并设置默认值为 0
binder.setDisallowedFields("id");
binder.registerCustomEditor(Long.class, new CustomNumberEditor(Long.class, true));
}
}
在上面的代码中,我们定义了一个名为 GlobalControllerAdvice 的控制器增强类,使用 @InitBinder 注解定义了一个名为 initBinder() 的方法。在这个方法中,我们通过 WebDataBinder 对象添加了一个全局日期格式化器,禁用了 id 参数的绑定,以及注册了一个 Long 类型的属性编辑器。
需要注意的是,@InitBinder 注解只针对当前控制器有效,如果需要应用到整个应用程序中,我们还需要在每个控制器类中都定义一个带有 @InitBinder 注解的方法。
总之,@InitBinder 注解用于将公共数据绑定到 WebDataBinder 对象中,可以对表单提交的数据进行自定义的处理,从而提高开发效率和系统可维护性。
22. @Lazy:标记 bean 为懒加载。
@Lazy 是 Spring 框架中的注解之一,它用于控制 Bean 的实例化时间。通过在容器中标记一个 Bean 为 @Lazy,可以让 Spring 容器在第一次使用这个 Bean 时再进行实例化。相对应的,如果不加 @Lazy 注解,则默认情况下 Spring 容器会在启动时就实例化该 Bean。
以下是一个使用 @Lazy 注解的例子:
@Service
@Lazy
public class UserService {
// ...
}
在上面的代码中,我们定义了一个名为 UserService 的服务类,并使用 @Service 和 @Lazy 注解标记了该类。通过使用 @Lazy 注解,Spring 容器将在第一次使用 UserService 的实例时才进行实例化,而不是在启动时就实例化。
需要注意的是,@Lazy 注解只影响单例 Bean 的实例化,对于原型(prototype)作用域的 Bean 来说,每次获取都会创建一个新的实例。同时,@Lazy 注解也可以用在依赖注入(DI)属性上,表示延迟注入该属性的实际对象。
总之,@Lazy 注解用于控制 Bean 实例化的时间,可以提高系统的性能和资源利用效率。但是需要根据具体的场景来考虑是否使用,避免出现应用程序行为与预期不符的情况。
23. @MetaAnnotation:定义元注解,即可用于自定义注解上的注解。
@MetaAnnotation 是指自定义注解上的注解,在 Spring 框架中用于构建基于注解的开发(Annotation-based Development)。通过组合多个注解,并将它们作为元注解(Meta Annotation)应用到自定义注解上,可以简化代码编写和维护工作。
在 Spring 框架中,有多个元注解可用于自定义注解上,例如:
- @Retention:指定注解的生命周期,包括 RetentionPolicy.SOURCE、RetentionPolicy.CLASS 和 RetentionPolicy.RUNTIME;
- @Target:指定注解可以被应用到哪些元素上,例如 ElementType.TYPE、ElementType.FIELD 等;
- @Documented:指定该注解是否出现在 Javadoc 中;
- @Inherited:指定子类是否继承注解;
如果我们希望某个自定义注解具有某些特定的功能,可以使用以上元注解进行组合。以下是一个使用 @MetaAnnotation 的例子:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Inherited
public @interface MyAnnotation {
String value() default "hello";
}
在上面的代码中,我们定义了一个名为 MyAnnotation 的自定义注解,并对其进行了元注解的组合。通过这种方式,我们可以控制该注解的生命周期、适用范围、出现在 Javadoc 中或者能否被子类继承等。
需要注意的是,Spring 框架中的注解和元注解是通过 Java 中的反射机制进行解析和使用的。当我们应用一个自定义注解时,Spring 容器会通过元注解来获取该注解的属性、作用范围等信息,并进一步控制系统中组件的行为。
总之,@MetaAnnotation 是 Spring 框架中一种非常常见的注解,可以通过元注解的组合方式扩展、定制各类自定义注解的行为和属性。
24. @ModelAttribute:方法参数注解,用于从请求对象中填充 POJO 对象的属性值。
@ModelAttribute 是 Spring MVC 中的一个注解,用于将请求参数绑定到方法参数上。它通常与 @RequestMapping 注解一起使用,在处理 HTTP 请求时可以将请求中的数据自动地绑定到对应的方法参数上。
使用 @ModelAttribute 注解可以方便我们将请求参数分成多个对象进行处理,比如将表单数据分成表单头部数据和表单内容数据。通过在方法参数上添加 @ModelAttribute 注解,Spring MVC 将会尝试从请求中获取对应的属性值,并将其绑定到该参数上。如果在请求参数中找不到对应的属性值,则使用默认值或者抛出异常。
以下是一个使用 @ModelAttribute 的例子:
假设有一个 User 类,包含了用户信息,我们希望将用户信息接收并进行处理,代码如下所示:
@Controller
@RequestMapping("/user")
public class UserController {
@PostMapping("/add")
public String addUser(@ModelAttribute User user) {
System.out.println(user.getName());
System.out.println(user.getEmail());
// ...其他操作
return "success";
}
}
在上面的代码中,我们定义了一个名为 addUser 的方法,并使用 @ModelAttribute 注解标记了方法参数 User。在处理 POST /user/add 请求的时候,Spring MVC 会取出所有名为 name 和 email 的请求参数,并将它们自动转换为 User 对象,最终传递给 addUser 方法。
需要注意的是,@ModelAttribute 注解还可以用于修饰方法,表示该方法将会在每个请求之前执行,并将指定的返回值绑定到模型(Model)中。在 Spring MVC 的视图渲染过程中,可以通过直接引用该返回值的变量名来获取其值。
总之,@ModelAttribute 是 Spring MVC 中的一个重要注解,可以方便地将请求参数绑定到方法参数上,实现灵活的开发模式。
25. @Order:指示组件应在其所有注入器已装配完成后被排序。
@Order 是 Spring 框架中的一个注解,用于控制组件(Component)之间的加载顺序。它通常用于系统启动阶段对组件进行排序,从而优化应用程序的性能和稳定性。
在 Spring 中,涉及到多个组件的时候,如果这些组件之间存在依赖关系,那么就需要确保它们的加载顺序是正确的。通过给组件加上 @Order 注解,我们可以指定它们的加载顺序。Spring 将根据 @Order 的值从小到大排序,数值越小的组件越先被加载。
以下是示例代码:
@Component
@Order(1)
public class ComponentA implements ApplicationRunner {
// ...
}
@Component
@Order(2)
public class ComponentB implements ApplicationRunner {
// ...
}
@Component
@Order(3)
public class ComponentC implements ApplicationRunner {
// ...
}
在上面的代码中,我们定义了三个带有 @Order 注解的组件:ComponentA、ComponentB 和 ComponentC,并分别给它们设置了不同的排序值。在 Spring 容器启动的过程中,Spring 会根据 @Order 来确定组件的加载顺序,这样一来,每个组件就能按照正确的顺序被加载和初始化了。
需要注意的是,@Order 注解只适用于实现了 Ordered 接口或者实现了 Comparable 接口的类。对于没有实现这两个接口的类,可以使用 @Priority 注解来完成相同的功能,它与 @Order 注解的使用方式类似。
总之,@Order 是一个很重要的注解,用于控制 Spring 容器中组件的加载顺序。通过使用 @Order,我们可以有效地优化应用程序的性能和稳定性。
26. @PostMapping:处理 HTTP POST 请求。
@PostMapping 是 Spring MVC 框架中用来处理 POST 请求的注解。它通常与 @RequestMapping 注解一起使用,并可以指定一个路径作为该方法映射到的请求地址。
使用 @PostMapping 可以让开发者很方便地定义一个 POST 请求处理器,从而将 HTTP 请求参数转换成 Java 方法的输入参数,并进行统一处理。下面是一个简单的示例:
@RestController
@RequestMapping("/user")
public class UserController {
@PostMapping("")
public User addUser(@RequestParam("name") String name, @RequestParam("age") int age) {
// 处理添加用户的操作
User user = new User();
user.setName(name);
user.setAge(age);
return user;
}
}
在上面的代码中,我们定义了一个名为 addUser 的方法,然后给这个方法添加了 @PostMapping 和 @RequestMapping 注解。这个方法接受两个参数 name 和 age,这些参数将会被自动从 HTTP 请求中提取出来,并转换为 Java 对象类型。
需要注意的是,在 @PostMapping 注解中不需要再指定请求方式,因为它已经明确指定为 POST 请求处理器了。此外,@RequestParam 注解用来指定 HTTP 请求参数和 Java 方法参数之间的名称映射关系。
总之,@PostMapping 是 Spring MVC 中处理 POST 请求的重要注解。它可以帮助我们更灵活地定义 HTTP 请求处理器,从而方便地管理和维护 Web 应用程序。
27. @Primary:注释为默认首选 bean。
@Primary 注解是在 Spring 框架中用于指定默认的依赖注入实例的注解。当一个接口有多个实现类时,可以通过在其中一个实现类上加上 @Primary 注解,来让 Spring 容器优先选择该实现类作为依赖注入的对象。
下面是一个使用 @Primary 注解的示例:
@Configuration
public class AppConfig {
@Bean("singer1")
public Singer singer1() {
return new SingerImpl1();
}
@Bean("singer2")
@Primary
public Singer singer2() {
return new SingerImpl2();
}
}
在上面的代码中,我们定义了两个不同的 Bean:singer1 和 singer2。SingerImpl1 和 SingerImpl2 分别是 Singer 接口的两个实现类。注意到 singer2 上添加了 @Primary 注解,这表示它是默认的依赖注入实例。如果我们需要将 Singer 接口以依赖注入方式注入其他的类中,且没有指定具体选择哪个 Bean,则 Spring 会自动选择 singer2 Bean 作为依赖注入的对象。
需要注意的是,@Primary 注解只能用于一组具有相同类型的 Bean 中。此外,在多个位置使用 @Primary 注解指定默认的 Bean 时,如果存在歧义,Spring 将抛出 NoUniqueBeanDefinitionException 异常。
总之,@Primary 注解是用于在 Spring 容器中指定默认依赖注入实例的注解。通过使用 @Primary,我们可以很方便地指定一个 Bean 作为默认的依赖注入实例,从而提高应用程序的可维护性和灵活性。
28. @Profile:确定配置在特定情况或环境下使用的 bean。
@Profile 注解是在 Spring 框架中用于指定在不同环境下使用不同的 Bean 实例的注解。通过使用 @Profile,我们可以让 Spring 在不同的运行时环境中选择不同的 Bean。
一个常见例子是,在开发和生产环境中,我们可能需要使用不同的数据库或第三方服务。在这种情况下,我们可以定义两个不同的 Bean,并使用 @Profile 注解来区分它们,如下所示:
@Configuration
public class AppConfig {
@Bean
@Profile("dev")
public DatabaseConnection devDatabaseConnection() {
return new DevDatabaseConnection();
}
@Bean
@Profile("prod")
public DatabaseConnection prodDatabaseConnection() {
return new ProdDatabaseConnection();
}
}
在上面的代码中,我们定义了两个不同的 Bean:devDatabaseConnection 和 prodDatabaseConnection,并通过 @Profile 注解来区分它们。如果在开发环境中运行该应用程序,则会使用 devDatabaseConnection,而如果在生产环境中运行,则会使用 prodDatabaseConnection。
需要注意的是,@Profile 注解还可以与 @Component、@Configuration 等其他注解一起使用。例如,我们可以给一个被 @Component 或 @Service 注解的类添加一个 @Profile 注解,从而控制是否扫描到该 Bean 类。
总之,@Profile 注解是在 Spring 中控制在不同环境下使用不同的 Bean 实例的重要注解。通过使用 @Profile,我们可以很方便地定义和管理不同环境下的 Bean 实例,从而提高应用程序的灵活性和可维护性。
29. @PropertySource:加载外部属性文件以替换当前环境中的占位符。
@PropertySource 注解是在 Spring 框架中用于读取外部属性文件的注解。通过使用 @PropertySource,我们可以将一个外部的属性文件加载到 Spring 的环境中,并使得这些属性可以在应用程序运行时被访问和使用。
下面是一个使用 @PropertySource 注解的示例:
@Configuration
@PropertySource("classpath:db.properties")
public class DatabaseConfig {
@Autowired
private Environment env;
@Bean
public DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(env.getProperty("db.driver"));
dataSource.setUrl(env.getProperty("db.url"));
dataSource.setUsername(env.getProperty("db.username"));
dataSource.setPassword(env.getProperty("db.password"));
return dataSource;
}
}
在上面的代码中,我们使用 @PropertySource 注解来加载一个 db.properties 文件,该文件位于类路径的根目录下。然后我们通过 @Autowired 注解来注入一个 Environment 对象,并利用其 getProperty 方法来获取属性值。最后,我们使用这些属性来配置一个数据源 Bean。
需要注意的是,@PropertySource 注解可以定义在任何一个被 @Configuration 或 @ComponentScan 注解的类上,从而使得整个应用程序能够共享属性文件中的属性。同时,也可以定义多个 @PropertySource 注解以加载多个属性文件,并使用不同的 value、location、name 等参数来给每一个属性文件一个唯一的标识符。
总之,@PropertySource 注解是一个用于读取外部属性文件的重要注解,在 Spring 应用程序开发中常常被使用。通过该注解,我们可以很方便地将属性文件中的属性加载到 Spring 环境中,并在应用程序运行时使用这些属性来配置 Bean 实例。
30. @Qualifier:使用合格名选择 Bean。
@Qualifier 注解是在 Spring 框架中用于指定 Bean 的名称或 ID 的注解。在一些情况下,当多个同类型的 Bean 实例存在时,Spring 会无法确定要使用哪个 Bean 实例,这时我们可以使用 @Qualifier 来明确指定要使用哪个 Bean 实例。
下面是一个使用 @Qualifier 注解的示例:
@Service
public class OrderServiceImpl implements OrderService {
// 使用 @Autowired 和 @Qualifier 注解合并进行依赖注入
@Autowired
@Qualifier("mysqlOrderDao")
private OrderDao orderDao;
@Override
public void save(Order order) {
orderDao.save(order);
}
}
在上面的代码中,我们使用 @Autowired 和 @Qualifier 注解来注入一个 OrderDao 的实现类。@Qualifier 中指定了要使用的 Bean 的名称或 ID,这样就可以确保正确地注入一个指定的 Bean 实例。
需要注意的是,当同类型的多个 Bean 实例存在时,Spring 会默认使用其 Bean 的名称或 ID 来匹配,并将匹配到的 Bean 注入到目标对象中。如果多个 Bean 实例有相同的名称或 ID,则会抛出 NoSuchBeanDefinitionException 异常。
总之,@Qualifier 注解是一个在 Spring 中用于指定 Bean 名称或 ID 的重要注解,在多个同类型的 Bean 实例存在时,可以通过 @Qualifier 明确指定要使用的 Bean 实例,从而解决依赖注入的歧义问题。
31. @RequestMapping:将 HTTP Request 映射到处理程序方法。
@RequestMapping 注解是在 Spring MVC 框架中用于将 HTTP 请求映射到处理方法(Controller 方法)的注解。通过使用 @RequestMapping,我们可以将指定的 URL 地址映射到一个特定的 Controller 方法上,从而实现对 HTTP 请求的处理。
下面是一个使用 @RequestMapping 注解的示例:
@Controller
@RequestMapping("/users")
public class UserController {
@GetMapping("/{id}")
public ModelAndView getUser(@PathVariable("id") Long id) {
// 处理获取用户信息的请求
User user = userService.getUserById(id);
ModelAndView mav = new ModelAndView("user");
mav.addObject("user", user);
return mav;
}
@PostMapping
@ResponseBody
public String createUser(@RequestBody User user) {
// 处理创建用户的请求
userService.createUser(user);
return "success";
}
}
在上面的代码中,我们将 @RequestMapping 注解放置在 Controller 类上,并指定了一个"/users"的 URL 前缀。然后我们在类中定义了两个处理方法,分别对应了 GET 和 POST 请求。在这两个方法上,我们使用了 @GetMapping 和 @PostMapping 注解来指定了请求的方法类型(GET/POST)和请求路径(URL 映射)。同时,在 @GetMapping 注解上还用到了 @PathVariable 注解,用于接收路径参数。
需要注意的是,当在不同的 Controller 类中都存在相同的请求 URL 时,可以使用 @RequestMapping 的 value 属性指定更具体的 URL 地址,以避免冲突。@RequestMapping 还可以用于设置其他的请求参数,例如 method、params、headers 等。
总之,@RequestMapping 注解是在 Spring MVC 中用于将 HTTP 请求映射到处理方法的重要注解。它简便了我们对 HTTP 请求和响应的处理,使得我们可以更加专注于业务逻辑的实现。
32. @Repository:声明一个类作为数据访问对象(DAO)的类。
@Repository 注解是 Spring 框架中用于将 DAO 层的类识别为 Bean,从而使其能够被 Spring 容器管理的注解。通常,我们会在 DAO 层的实现类上使用 @Repository 注解来表示这个类是一个数据访问对象,用于操作数据库或其他持久化方法。
下面是一个使用 @Repository 注解的示例:
@Repository
public class UserRepositoryImpl implements UserRepository {
@Autowired
private JdbcTemplate jdbcTemplate;
public User findById(Long id) {
// 使用 JdbcTemplate 查询数据库操作
String sql = "SELECT id, name FROM users WHERE id = ?";
return jdbcTemplate.queryForObject(sql, new Object[] {id}, new BeanPropertyRowMapper<>(User.class));
}
public void save(User user) {
// 使用 JdbcTemplate 更新数据库操作
String sql = "INSERT INTO users (name) VALUES (?)";
jdbcTemplate.update(sql, user.getName());
}
}
在上面的代码中,我们在 UserRepositoryImpl 类上添加了 @Repository 注解,将其标记为一个数据访问对象。然后,我们可以在类中注入 JdbcTemplate 对象,使用它来完成对数据库的查询和更新操作。
需要注意的是,@Repository 注解与 @Service、@Component 等注解一样,都会被 Spring 自动扫描并注册到容器中。通过 @Autowired 注解,我们可以将需要依赖 UserRepository 的组件自动装配到 UserRepositoryImpl 实例中。
总之,@Repository 注解是 Spring 框架中用于将 DAO 层的实现类识别为 Bean 的注解。通过 @Repository 注解,我们可以让 Spring 管理这些 DAO 类的生命周期,并提供方便的连接池和异常处理机制,使得对数据库的访问更加便捷和安全。
33. @RequestHeader:获取请求头中指定名称的值。
@RequestHeader 注解是 Spring 框架中用于获取 HTTP 请求头信息的注解,通常用于需要读取客户端请求头信息的 Controller 方法参数中。
下面是一个使用 @RequestHeader 注解获取请求头信息的示例:
@Controller
@RequestMapping("/users")
public class UserController {
@GetMapping("/{id}")
public ModelAndView getUser(@PathVariable("id") Long id, @RequestHeader("User-Agent") String userAgent) {
// 处理获取用户信息的请求并输出 User Agent 信息
System.out.println("User-Agent: " + userAgent);
User user = userService.getUserById(id);
ModelAndView mav = new ModelAndView("user");
mav.addObject("user", user);
return mav;
}
}
在上面的代码中,我们在 getUser() 方法中添加了 @RequestHeader 注解,用于获取 “User-Agent” 请求头部信息。当客户端向服务器发送请求时,在请求头中携带了 User-Agent 的信息,而该信息被 @RequestHeader 注解识别出来后,会自动传入方法参数中进行处理。
除了 @RequestHeader 注解,Spring 还提供了其他类似的注解,例如 @RequestParam、@RequestBody、@PathVariable 等,这些注解也可以从 HTTP 请求中获取不同类型的数据,并注入到 Controller 方法中进行处理。
总之,@RequestHeader 注解是 Spring 框架中用于获取 HTTP 请求头信息的注解。通过使用该注解,我们可以方便地获取客户端请求头信息,并进行相应的业务处理。
34. @RequestParam:从请求参数中获取值。
@RequestParam 注解是 Spring 框架中用于获取 HTTP 请求参数的注解,通常用于需要读取客户端请求参数的 Controller 方法参数中。
下面是一个使用 @RequestParam 注解获取请求参数的示例:
@Controller
@RequestMapping("/users")
public class UserController {
@GetMapping("list")
public ModelAndView getUserList(@RequestParam(name = "page", required = true) Integer page,
@RequestParam(name = "size", defaultValue = "10") Integer size) {
// 获取用户列表并输出分页信息
System.out.println("page: " + page + ", size: " + size);
List<User> userList = userService.getUserList(page, size);
ModelAndView mav = new ModelAndView("userList");
mav.addObject("userList", userList);
return mav;
}
}
在上面的代码中,我们在 getUserList() 方法中添加了两个 @RequestParam 注解,用于获取客户端传递的 “page” 和 “size” 请求参数。其中,required 属性指定了是否必须传递该参数,defaultValue 属性则指定了默认值。
除了 @RequestParam 注解,Spring 还提供了其他类似的注解,例如 @RequestHeader、@RequestBody、@PathVariable 等,这些注解也可以从 HTTP 请求中获取不同类型的数据,并注入到 Controller 方法中进行处理。
总之,@RequestParam 注解是 Spring 框架中用于获取 HTTP 请求参数的注解。通过使用该注解,我们可以方便地获取客户端请求参数,并进行相应的业务处理。
35. @RequestBody:从请求体中获取值。
@RequestBody 注解是 Spring 框架中用于获取 HTTP 请求体信息的注解,通常用于需要读取客户端请求体中的参数的 Controller 方法参数中。
下面是一个使用 @RequestBody 注解获取请求体信息的示例:
@RestController
@RequestMapping("/users")
public class UserController {
@PostMapping
public ResponseEntity<User> createUser(@RequestBody User user) {
// 处理创建用户的请求并返回创建成功的用户信息
User createdUser = userService.createUser(user);
return ResponseEntity.ok(createdUser);
}
}
在上面的代码中,我们在 createUser() 方法中添加了 @RequestBody 注解,用于获取客户端传递的用户信息。在客户端发送 POST 请求时,通过设置请求体来包含用户的信息,在服务端收到请求后,就可以通过 @RequestBody 注解将请求体中的信息自动地转换为 User 对象,从而进行业务处理。
除了 @RequestBody 注解,Spring 还提供了其他类似的注解,例如 @RequestParam、@RequestHeader、@PathVariable 等,这些注解也可以从 HTTP 请求中获取不同类型的数据,并注入到 Controller 方法中进行处理。
总之,@RequestBody 注解是 Spring 框架中用于获取 HTTP 请求体信息的注解。通过使用该注解,我们可以方便地获取客户端请求体中的参数,并进行相应的业务处理。
36. @ResponseStatus:指示 Spring 处理程序方法的 HTTP 响应状态。
@ResponseStatus 是 Spring 框架中的一个注解,用于为处理请求时的响应设置自定义状态码和原因短语。在接口方法上使用 @ResponseStatus 注解后,可以将方法所返回的结果自动转换为对应的 HTTP 响应格式,并设置自定义状态码和原因短语。
下面是一个使用 @ResponseStatus 注解设置自定义状态码和原因短语的示例:
@RestController
@RequestMapping("/users")
public class UserController {
@GetMapping("{userId}")
@ResponseStatus(HttpStatus.OK)
public User getUserById(@PathVariable("userId") Long userId) {
// 获取指定 ID 的用户信息并返回
User user = userService.getUserById(userId);
if (user == null) {
throw new UserNotFoundException();
}
return user;
}
@ExceptionHandler(UserNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public void handleUserNotFound() {
// 处理用户不存在的异常
}
}
在上面的代码中,我们在 getUserById() 方法上添加了 @ResponseStatus 注解,并设置其状态码为 HttpStatus.OK 。这样,在方法执行结束后,Spring 就会将该方法的返回值自动转换为 HTTP 响应,并设置状态码为 200(即 OK)。
此外,我们还通过 @ExceptionHandler 注解配合 @ResponseStatus 注解来实现了一个处理用户不存在错误的方法。当 UserService.getUserById() 返回空值时,getUserById() 方法就会抛出 UserNotFoundException 异常,并交给 handleUserNotFound() 方法进行处理。在 handleUserNotFound() 方法中,我们使用 @ResponseStatus 注解设置了异常对应的状态码为 HttpStatus.NOT_FOUND(即 404)。
总之,@ResponseStatus 注解是 Spring 框架中用于设置自定义状态码和原因短语的注解。使用该注解可以方便地设置响应的 HTTP 状态码,并将方法返回值自动转换为对应的 HTTP 响应。
37. @Resource:通常作为 JNDI 的替代方案来注入类、属性或方法。
@Resource 是 Java EE 中的一个注解,用于标记需要依赖注入的类或接口对象。在 Java EE 应用程序中,由容器管理对象的生命周期和依赖关系,@Resource 注解就可以指示容器将目标资源注入到应用程序中。
在 Spring 框架中,@Resource 注解通常被 @Autowired 和 @Qualifier 注解所替代,用于完成依赖注入。与 @Autowired 相似,@Resource 也可以将一个 bean 对象自动注入到另一个 bean 对象中,但是它们也存在一些区别:
-
@Resource 可以通过名称、类型来注入依赖,而 @Autowired 直接根据类型注入依赖。(当使用 @Autowired 注解时,如果有多个类型相同的 bean,则必须使用 @Qualifier 注解来指定具体的 bean 名称)
-
@Resource 默认按名称进行装配(即默认情况下会找同名的 Bean 进行注入),而 @Autowired 默认按类型装配。
下面是一个使用 @Resource 注解完成依赖注入的示例:
@Service
public class UserServiceImpl implements UserService {
@Resource
private UserRepository userRepository; // 自动注入
// ...
}
在上面的代码中,我们在 UserServiceImpl 类中添加了 @Resource 注解,将 UserRepository 对象注入到 userService 实例中。默认情况下,Spring 会根据属性名 “userRepository” 来查找同名的 Bean,并将其注入到 userService 实例中。
需要注意的是,@Resource 注解默认情况下也会使用类型来查找同类型的 Bean。如果出现了多个类型相同的 Bean,则可以通过 name 属性来指定具体要注入的 Bean 名称。例如:
@Service
public class UserServiceImpl implements UserService {
@Resource(name="userRepository1" )
private UserRepository userRepository; // 自动注入
// ...
}
在上面的代码中,我们将 name 属性设置为 “userRepository1”,这样 Spring 就会根据名称来查找对应的 Bean,并且将其注入到 userService 实例中。
总之,@Resource 注解是 Java EE 中用于依赖注入的注解,而在 Spring 框架中则通常被 @Autowired 和 @Qualifier 注解所替代。与 @Autowired 相比,@Resource 更加灵活,并支持按名称和类型来查找 Bean。
38. @Scheduled:用于创建调度任务。
@Scheduled 是 Spring 中的一个注解,用于实现定时任务。使用 @Scheduled 注解可以根据指定的时间间隔或固定的时间点来执行任务方法。
下面是一个基本的示例:
@Component
public class MyTask {
@Scheduled(fixedRate = 5000)
public void task() {
// 每隔 5 秒钟执行一次该方法
System.out.println("Executing task...");
// ...
}
}
在上面的代码中,我们定义了一个名为 MyTask 的组件,并用 @Scheduled 注解标记了一个名为 task 的方法。这里使用了 fixedRate 属性,其中 5000 表示每隔 5 秒钟就会执行一次该方法。
除了 fixedRate 属性外,@Scheduled 注解还支持另外两个常见的属性:
- cron:使用 Cron 表达式指定任务的执行时间。例如:"0 0/5 * * * ?"表示每隔 5 分钟执行一次任务。
- fixedDelay:表示从上一次任务结束开始到下一次任务开始的时间间隔。
下面是一个使用 Cron 表达式的示例:
@Component
public class MyTask {
@Scheduled(cron = "0 0/5 * * * ?")
public void task() {
// 每隔 5 分钟执行一次该方法
System.out.println("Executing task...");
// ...
}
}
在上面的代码中,我们将 @Scheduled 注解的 cron 属性设置为 “0 0/5 * * * ?”,表示每隔 5 分钟就会执行该方法。
总之,@Scheduled 注解是 Spring 中用于实现定时任务的注解,可以根据指定的时间间隔或固定的时间点来执行任务方法。可以通过设置 fixedRate、fixedDelay 或 cron 属性来指定任务的执行方式。
39. @Scope:标识 bean 的作用域。
@Scope 是 Spring 中的一个注解,用于指示 Spring IOC 容器如何管理 Bean 实例的作用域。Spring 容器可以管理多个 Bean 实例,并为这些实例提供不同的访问方式。
Spring IOC 容器默认提供了以下四种作用域:
- singleton:在整个应用程序中只创建一个实例。这是 Spring 的默认作用域。
- prototype:每次请求时都创建一个新的实例。
- session:在每个 HTTP 会话中创建一个实例(仅在使用 Spring Web 应用程序时有效)。
- request:在每个 HTTP 请求中创建一个实例(仅在使用 Spring Web 应用程序时有效)。
除了以上四种作用域外,Spring 还支持其他一些作用域,比如 thread、globalSession 等特定的 Servlet API 作用域。
下面是一个使用 @Scope 注解定义 Bean 作用域的示例:
@Component
@Scope("prototype") // 声明 Bean 的作用域为 prototype
public class MyBean {
// ...
}
在上面的代码中,我们使用 @Component 声明了一个名为 MyBean 的组件,并使用 @Scope 注解将其作用域设置为 prototype。
需要注意的是,@Scope 注解还支持通过属性值来指定 Bean 的作用域,例如:
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class MyBean {
// ...
}
在上面的代码中,我们使用 value 属性来指定 Bean 的作用域为 prototype,并通过 proxyMode 属性来表明 Spring 应该为该 Bean 创建一个代理对象。
总之,@Scope 注解是 Spring 中用于指示 Bean 作用域的注解。通过设置不同的作用域类型,可以控制 Spring IOC 容器如何管理 Bean 实例。
40. @Service:声明一个类作为服务类。
@Service 是 Spring 中的一个注解,用于标记一个类为业务层(Service 层)组件。Service 组件通常用来处理应用程序的业务逻辑,并且与底层数据访问层进行交互。
使用 @Service 注解可以将一个类声明为 Spring Bean,并将其注册到 Spring IOC 容器中。在需要使用该组件时,可以通过将它作为构造函数参数或属性来注入其实例。这种方式可以让开发人员更加方便地管理和维护代码,同时也提高了代码的可重用性和测试性。
下面是一个简单的示例:
@Service // 声明该类为 Service 层组件
public class UserService {
private final UserRepository userRepository;
@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public List<User> getUsers() {
return userRepository.findAll();
}
}
在上面的代码中,我们使用 @Service 注解标记了一个名为 UserService 的类,将其声明为业务层组件。其中,UserService 类的构造函数接受一个名为 userRepository 的 UserRepository 实例作为参数,并将其保存在成员变量中。通过调用 UserRepository 的 findAll 方法,UserService 提供了获取所有用户的功能。
除了 @Service 注解外,Spring 还提供了其他一些注解,如@Controller、@Repository 和 @Component 等,可以用于标记不同类型的 Spring Bean。这些注解本质上是相同的,都能让 Spring 将一个类注册为 Bean 并提供相应的 IOC 支持。
总之,@Service 注解是 Spring 中用于标记业务层组件的注解。通过使用 @Service 注解,可以将一个类声明为 Spring Bean,并将其注册到 Spring IOC 容器中,以实现依赖注入和管理。
41. @SessionAttributes:指定会话属性。
@SessionAttributes 是 Spring 中的一个注解,用于将 Model 属性保存到 HTTP 会话(session)中。当控制器处理请求时,它可以使用这些属性来获取值或更新值。
使用 @SessionAttributes 注解可以让开发人员更加方便地处理一些常见的场景,如表单提交、文件上传和分页查询等。此外,它还可以用来实现登录信息的存储和跨请求的共享数据等功能。
下面是一个简单的示例:
@Controller
@RequestMapping("/users")
@SessionAttributes("user") // 声明需要保存到 session 中的属性名称
public class UserController {
@GetMapping("/{id}")
public String getUser(@PathVariable Long id, Model model) {
// 从数据库中获取用户信息,并将其保存到 Model 中
User user = userService.getUserById(id);
model.addAttribute("user", user);
return "user-details";
}
@PostMapping("/{id}/update")
public String updateUser(@PathVariable Long id, @ModelAttribute("user") User user) {
// 更新用户信息
userService.updateUser(user);
return "redirect:/users/" + id;
}
}
在上面的代码中,我们使用 @SessionAttributes 注解声明将名为 “user” 的属性保存到 HTTP 会话中。在控制器的处理方法中,我们使用 Model 实例将从数据库中获取的用户对象添加到 Model 中,并返回一个包含用户详细信息的视图。在更新用户信息时,我们使用 @ModelAttribute (“user”) 注解将请求参数绑定到名为 “user” 的属性上,并调用 UserService 方法更新用户信息。最后,我们将用户重定向到用户详细信息页面。
需要注意的是,@SessionAttributes 注解仅支持保存模型属性,不支持保存表单参数或其他类型的数据。此外,由于它会将对应的属性保存到 HTTP 会话中,因此在使用时需要注意安全性和性能问题,避免出现与会话相关的潜在风险和资源浪费等问题。
总之,@SessionAttributes 注解是 Spring 中用于将 Model 属性保存到 HTTP 会话中的注解。通过使用 @SessionAttributes 注解,开发人员可以更加方便地处理控制器中的业务逻辑,并实现共享数据和状态的功能。
42. @Transactional:启用事务管理。
@Transactional
是一个Java注解,用于指示一段代码应该在一个事务中执行。这意味着如果所有操作都成功执行,则代码所做的更改才会提交到数据库中,否则所有更改都将回滚。事务确保数据的完整性和一致性,特别适用于多用户系统,在这些系统中,并发请求可能会同时访问和修改同一数据。
以下是一个 @Transactional
的例子:
@Service
public class UserService {
private final UserRepository userRepository;
@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Transactional
public User createUser(String username, String password) {
User user = new User(username, password);
return userRepository.save(user);
}
}
在上述例子中,我们定义了一个名为 createUser
的方法并使用 @Transactional
注解,使其执行过程位于一个事务中。如果在保存用户实体时发生任何错误,引发异常或抛出运行时异常,则该事务将被回滚。否则,此事务将提交,并且用户将成功被持久化到数据库中。
43. @Validated:用于方法参数验证。
@Validated
是一个 Spring Framework 提供的用于方法级别参数校验的注解。它可以用于在方法入参上应用 Bean Validation 标准的验证规则,确保输入的数据符合要求。
使用 @Validated
注解时需要搭配标准的 Bean Validation 的注解,例如 @NotNull
, @NotBlank
, @Size
等等。这些注解提供了各种验证规则,用来验证方法的输入参数是否符合规范。
下面是一个示例:
@Service
public class UserService {
private final UserRepository userRepository;
@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
public User createUser(@Validated CreateUserRequest request) {
User user = new User(request.getUsername(), request.getPassword());
return userRepository.save(user);
}
}
在上述例子中,我们定义了一个名为 createUser
的方法并且使用了 @Validated
注解在方法的参数上,使得输入的 CreateUserRequest
对象会被校验。如果该对象中的属性不符合相应的验证规则,就会抛出 ConstraintViolationException 异常。
通过使用 @Validated
注解,Spring Boot 可以在方法执行前自动对参数进行验证,如果参数不满足约束条件,则会引发异常并返回错误消息。使用此注释将有助于增强代码的质量和安全性,并避免潜在的漏洞。
44. @PatchMapping:处理 HTTP PATCH 请求。
@PatchMapping
是 Spring MVC 的注解之一,用于将 HTTP PATCH 请求映射到方法上。与其他常见的 HTTP 方法(如 GET、POST、PUT 和 DELETE)不同,PATCH 方法是用于部分更新资源的请求,而不是整个资源的替换。使用 @PatchMapping
注解可以帮助我们定义处理这种类型请求的控制器方法。
以下是一个简单的示例,演示如何使用 @PatchMapping
:
@RestController
@RequestMapping("/users/{id}")
public class UserController {
@Autowired
private UserRepository userRepository;
@PatchMapping("")
public User updateUserNameById(@PathVariable Long id, @RequestBody UserUpdateRequest request) {
User user = userRepository.getById(id);
user.setName(request.getName());
return userRepository.save(user);
}
}
上述示例中,我们在 UserController
类上拥有了一个基础的路径 /users/{id}
,并且为该路由下的 HTTP PATCH 请求映射了一个名为 updateUserNameById
的方法,该方法接收两个参数:一个 @PathVariable
标记的 id
和一个 @RequestBody
标记的 request
对象。我们从 UserRepository 中检索该用户数据,然后执行更新操作,并返回最新版本的用户。
需要注意的是,与其他的 HTTP 方法注解类似, @PatchMapping
也可以添加其他的注解来进一步限制请求匹配和参数绑定方面的条件,例如 @RequestParam
,@RequestHeader
等等。
45. @PathVariable:从请求 URI 模板中获取值。
@PathVariable
是 Spring MVC 中的一个注解,用于将 URL 路径中的模板变量绑定到方法参数上。
在一个包含路径参数的请求 URL 中,如 /users/{id}
,花括号中的 id
就是一个路径变量。通过在控制器方法的参数上加上 @PathVariable
注解,Spring 将尝试将该变量绑定到对应名称的参数上,并将其传递给该方法。例如:
@GetMapping("/users/{id}")
public User getUserById(@PathVariable Long id) {
return userRepository.findById(id);
}
在上述示例中,我们使用了 @GetMapping
注解来映射 HTTP GET 请求到 /users/{id}
路径,同时使用了 @PathVariable
注解将 id
绑定到方法参数上。
如果请求路径为 /users/123
,Spring 将会自动将 123 这个参数绑定到 id
参数上,以便在方法体内可以进行相应的业务操作。
需要注意的是,@PathVariable
注解要求方法参数名必须与路径变量名称相同,或者通过 @PathVariable("variableName")
显式指定变量名。此外,在{}
内可以设置正则表达式限制变量匹配,这些内容都可以在 Spring 的官方文档中得到更详细的说明。
46. @PutMapping:处理 HTTP PUT 请求。
@PutMapping
是 Spring MVC 中的一个注解,用于将 HTTP PUT 请求映射到控制器的处理方法上,以便为资源进行更新操作。
当客户端需要使用 PUT 方法来按照 ID 更新某个资源时,可以在 Spring 控制器中定义一个 @PutMapping
注解方法。例如:
@PutMapping("/users/{id}")
public ResponseEntity<User> updateUserById(@PathVariable Long id, @RequestBody User user) {
User updatedUser = userService.updateUser(id, user);
return new ResponseEntity<>(updatedUser, HttpStatus.OK);
}
在这个示例中,我们使用 @PutMapping
注解来映射 /users/{id}
路径上的 PUT 请求,并接受传入的 User
对象作为请求体。@PathVariable
注解用于绑定请求路径中的 id
变量到方法参数上。然后通过调用 UserService 的更新方法来更新用户对象并返回响应体。
需要注意的是,@PutMapping
方法应该是幂等的,也就是说,无论进行多少次 PUT 操作,最终结果应该都是一致的。这意味着方法中的操作不能随机改变底层数据或增加副作用。
在实际场景中,PUT 和 PATCH 方法通常会经常用于 RESTful API 的设计中。PUT 用来全量更新,PATCH 用来部分更新,具体如何使用需根据场景决定。
47. @TransactionalEventListener:声明一个异步的事务事件监听器。
@TransactionalEventListener
是 Spring Framework 中的一个注解,用于在事务提交完成后异步地处理一个事件。
当应用程序中发生某些特定事件时(例如用户注册、订单支付等),我们通常希望能够执行与该事件相关的业务逻辑。Spring 的事件机制提供了一种非常方便的方式来进行监听和响应事件。当事件触发时,Spring 将自动调用与该事件相关联的所有处理方法。
但是,有时候如果事件处理方法不需要在同一个事务内执行,或者我们希望在事务提交之后再执行某些操作,就需要使用 @TransactionalEventListener
注解。这个注解允许我们为事件处理方法指定一个事务模式,即它应该是一个完全独立的事务还是与正在运行的主事务一起运行。其中,默认情况下,事件监听方法会在抛出异常时回滚事务。
例如:
@Transactional
public class OrderService {
@Autowired
private ApplicationEventPublisher eventPublisher;
public void saveOrder(Order order) {
// 保存订单
orderRepository.save(order);
// 发布 OrderCreatedEvent 事件
eventPublisher.publishEvent(new OrderCreatedEvent(order));
}
}
@Component
public class OrderCreatedEventListener {
@TransactionalEventListener
public void onOrderCreate(OrderCreatedEvent event) {
// 执行其他需要异步执行的操作
// ...
}
}
在上述示例中,我们使用了 @Transactional
注解来标记 saveOrder()
方法,以确保保存订单操作在事务中执行。接着在方法中发布了一个事件,其中被发布的 OrderCreatedEvent
会触发 onOrderCreate()
方法的执行。
同时在 onOrderCreate()
方法上使用了 @TransactionalEventListener
注解,这个方法将在主事务提交之后异步地执行。因此,如果在保存订单时发生异常,该订单将不会被创建,也就不会触发事件,onOrderCreate()
方法也不会被调用。
需要注意的是,在使用 @TransactionalEventListener
注解时,我们必须通过 Spring 的事件发布器来手动触发事件(而不是在代码中直接调用其他组件的方法)。因为如果我们调用其他组件的方法,Spring 将无法在事务提交后异步触发事件,导致注解失效。
48. @Value:注入外部属性值。
@Value
是 Spring Framework 中的一个注解,用于将属性值绑定到一个具体的变量或方法参数上。
在项目开发中,我们通常会在配置文件中定义一些属性,例如数据库连接信息、缓存配置、日志级别等。通过使用 @Value
注解,我们可以轻松地将这些属性值注入到我们的代码中,从而使得配置更加灵活和可配置化。
例如,在 Spring Boot 中我们通常会使用 application.properties
或 application.yml
文件来管理应用程序的配置属性。假设我们要读取一个名为 config.server.url
的属性值,可以在代码中使用:
@Component
public class MyComponent {
@Value("${config.server.url}")
private String serverUrl;
// ...
}
在上述示例中,我们通过使用 @Value
注解将 config.server.url
属性值注入到了 serverUrl
字段中。${}
表示占位符,其中 ${config.server.url}
表示从配置文件中读取 config.server.url
属性值。需要注意的是,在属性值前面加上前缀 $
时,占位符需要被转义成 \$
。
另外,@Value
注解还可以直接用在方法参数上,用于获取配置属性值。例如:
@Service
public class MyService {
public void doSomething(@Value("${config.timeout}") int timeout) {
// ...
}
}
在上述示例中,我们使用 @Value
注解将 config.timeout
属性值注入到了 timeout
参数中。
需要注意的是,如果属性不存在时,默认情况下会抛出一个异常。但是可以使用 ${some.property:default-value}
的语法来为属性设置默认值。在这种情况下,如果 some.property
不存在,则使用 default-value
作为属性值。
49. @ValueConstants:标识注解的常量值。
@ValueConstants
是 Spring Framework 中的一个类,它定义了一些常量用于 @Value
注解中的默认值。
在使用 @Value
注解时,如果属性值不存在或者无法转换成对应的数据类型时,会使用 @Value
注解中指定的默认值。如果没有指定默认值,则会使用 @ValueConstants
中的默认值。
例如,NULL
常量表示默认的空字符串:
@Component
public class MyComponent {
@Value("${my.property:#{NULL}}")
private String myProperty;
// ...
}
在上述示例中,如果 my.property
属性不存在,则 myProperty
字段将被设置为 null
。如果我们不想把 null
作为默认值,则可以使用 @ValueConstants.EMPTY_STRING
表示空字符串。另外,还可以使用 @ValueConstants.DEFAULT_NONE
表示不设置默认值,此时如果属性不存在,则会抛出一个异常。
除了这些常量之外,@ValueConstants
还提供了一些其他的常量,如 INFINITY
、NEGATIVE_INFINITY
、NaN
等,用于表示一些特殊的字面量值。这些常量通常用于数值型的属性,例如:
@Component
public class MyComponent {
@Value("${my.timeout:#{T(java.lang.Double).POSITIVE_INFINITY}}")
private double timeout;
// ...
}
在上述示例中,我们使用 @ValueConstants.INFINITY
表示超时时间的默认值为正无穷。需要注意的是,为了使用这些常量,我们需要在表达式中使用 SpEL(Spring Expression Language)语法,以 #{...}
开头和结尾。同时,在前面加上 T()
表示调用 Java 类的静态方法,后面跟上类名和方法名即可。
50. @Valid:用于方法参数验证。
@Valid
是 Java 中的一个注解,在 Spring Framework 中经常用来校验请求参数或者对象属性的合法性。
通常情况下,我们需要编写一些方法来对输入参数进行校验,并抛出异常或返回错误信息。使用 @Valid
注解可以方便地将校验逻辑集成到 Spring MVC 或者 Spring Boot 应用中,让框架帮助我们完成校验工作。
例如,在 Spring MVC 中,我们可以在控制器方法的参数列表中使用 @Valid
注解来实现请求参数的校验。下面是一个简单的示例:
@RestController
@RequestMapping("/users")
public class UserController {
@PostMapping
public User createUser(@Valid @RequestBody User user) {
// 保存用户信息到数据库
}
// ...
}
在上述示例中,我们使用 @Valid
注解对 user
参数进行校验,如果校验失败则会抛出 MethodArgumentNotValidException
异常。校验的规则通常定义在 User
类的属性上,例如:
public class User {
@NotBlank
private String username;
@Pattern(regexp = "^[a-zA-Z0-9]+@[a-zA-Z0-9]+\\.[a-zA-Z]{2,}$", message = "Email 格式错误")
private String email;
// ...
}
在上述示例中,我们使用了 @NotBlank
和 @Pattern
注解对 username
和 email
属性进行了校验。@NotBlank
表示字符串必须不为空,并且去掉前后空格后长度必须大于 0。@Pattern
则表示字符串必须符合指定的正则表达式,否则会返回自定义的错误消息。
需要注意的是,除了 @Valid
注解之外,还有一些其他的校验注解,如 @NotNull
、@Min
、@Max
、@Size
、@Email
等。在实际使用中,我们可以根据具体的场景和需求选择适合的注解进行校验。另外,我们也可以自定义校验注解来满足特殊的校验要求。