首先什么是注解?

以前,XML是各大框架的青睐者,它以松耦合的方式完成了框架中几乎所有的配置,但是随着项目越来越庞大,XML的内容也越来越复杂,维护成本变得越来越高。

于是就有人提出来一种标记式高耦合的配置方式,注解。方法上可以进行注解,类上也可以注解,字段属性上也可以注解,反正几乎需要配置的地方都可以进行注解

关于注解和XML两种不同的配置模式,争论了好多年了,各有各的优劣,注解可以提供更大的便捷性,易于维护修改,但耦合度高,而 XML 相对于注解则是相反的

追求低耦合就要抛弃高效率,追求效率必然会遇到耦合。本文意不再辨析两者谁优谁劣,而在于以最简单的语言介绍注解相关的基本内容。

不使用注解和使用注解对比:
注解快速入门


@Controller

简单说Controller就是负责解析用户的输入,处理后返回相应的结果
标识一个该类是Spring MVC controller处理器,用来创建处理http请求的对象。
1.在 RESTful 接口中,Controller 接受用户的参数,从数据库中查找内容返回给用户或者将用户的请求更新到数据库中。
2.在 HTML 页面请求中,Controller 根据用户访问不同的 URL,渲染不同的模板得到 HTML 返回给用户。
3.在代理服务器中,Controller 将用户的请求转发到其他服务器上,并将其他服务器的处理结果返回给用户。

框架推荐 Controller 层主要对用户的请求参数进行处理(校验、转换),然后调用对应的 service 方法处理业务,得到业务结果后封装并返回:
1.获取用户通过 HTTP 传递过来的请求参数。
2.校验、组装参数。
3.调用 Service 进行业务处理,必要时处理转换 Service 的返回结果,让它适应用户的需求。
4.通过 HTTP 将结果响应给用户。

@Controller
public class TestController {
        @RequestMapping("/test")
        public String test(Map<String,Object> map){

            return "hello";
        }
}

@RestController

@RestController注解,相当于@Controller+@ResponseBody两个注解的结合。

返回json数据不需要在方法前面加@ResponseBody注解了,但使用@RestController这个注解,就不能返回jsp、html页面,视图解析器无法解析jsp,html页面

Spring4之后加入的注解,原来在@Controller中返回json需要@ResponseBody来配合,如果直接用@RestController替代@Controller就不需要再配置@ResponseBody,默认返回json格式。
@RestController=@Controller+@ResponseBody两个注解,
注解为止在controller类上,相当于整个类中所有方法的返回值都为json字符串

@RestController
public class TestController {
        @RequestMapping("/test")
        public String test(Map<String,Object> map){

            return "hello";
        }
}

@Service

用于标注业务层组件,以注解的方式把这个类注入到spring配置中。

service 是有用的相当于 xml配置中得bean id = service 也可以不指定 不指定相当于 bean id = com. service.service 就是这个类的全限定名,表示给当前类命名一个别名,方便注入到其他需要用到的类中;不加的话,默认别名就是当前类名,但是首字母小写 。
注解用于类上,标记当前类是一个service类,加上该注解会将当前类自动注入到spring容器中,不需要再在applicationContext.xml文件定义bean了。

简单理解就是:告诉spring,我这个service接口的实现类是这个,你帮我在spring容器里创建它。

**@Service(“userService”)**注解是告诉Spring,当Spring要创建UserServiceImpl的的实例时,bean的名字必须叫做"userService",这样当Action需要使用UserServiceImpl的的实例时,就可以由Spring创建好的"userService",然后注入给Action:在Action只需要声明一个名字叫“userService”的变量来接收由Spring注入的"userService"即可

如果不懂bean的同学可以参考Java Bean详解

JavaBean可以看成是一个黑盒子,即只需要知道其功能而不必管其内部结构的软件设备。

黑盒子只介绍和定义其外部特征和与其他部分的接口,如按钮、窗口、颜色、形状、句柄等。

@Service
public class TestService {
        public String test(Map<String,Object> map){
            return "hello";
        }
}

@Autowired

用来装配bean,都可以写在字段上,或者方法上。

spring中可以借助**@Autowired**注解描述属性,用于告诉spring这个属性的值由spring注入

@Autowired这个注解就是spring可以自动帮你把bean里面引用的对象的setter/getter方法省略,它会自动帮你set/get

默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,例如:@Autowired(required=false)
它还可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。 通过 @Autowired的使用来消除 set ,get方法。

在使用**@Autowired**之前,我们对一个bean配置起属性时,是这用用的

<property name="属性名" value=" 属性值"/>    

通过这种方式来,配置比较繁琐,而且代码比较多。在Spring 2.5 引入了 @Autowired 注释

@RestController
public class TestController {

        @Autowired(required=false)
        private TestService service;

        @RequestMapping("/test")
        public String test(Map<String,Object> map){

            return "hello";
        }
}

@RequestMapping

类定义: 提供初步的请求映射信息,相对于 WEB 应用的根目录。
RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
RequestMapping注解有六个属性,下面我们把她分成三类进行说明。
1、 value, method;
value:指定请求的实际地址,指定的地址可以是URI Template 模式;
method:指定请求的method类型, GET、POST、PUT、DELETE等;
2、 consumes,produces;
consumes:指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;
3、 params,headers;
params: 指定request中必须包含某些参数值是,才让该方法处理。
headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求。

@RestController
public class TestController {
        @RequestMapping("/test")
        public String test(Map<String,Object> map){

            return "hello";
        }
}

@Bean

@Bean 用于描述方法。该方法返回的对象会交给 Spring 容器管理,相当于配置文件中的 <bean id="" class=""/>@Bean 通常写在 @Configuration 类的方法上,方法名默认就是 Bean 名称,也可以通过 @Bean("user") 指定名称。

@Configuration
public class UserConfig {
    @Bean
    public User getUser() {
        System.out.println("创建 user 实例");
        return new User("张三", 26);
    }
}

@Component

spring框架中定义的用于描述一般bean对象的一个注解springBoot工程在启动时会自动扫描启动类所在的包及其子包中的类,并读取这些类的描述,加入这些类使用了类似@Component这样的注解描述,它会交给spring管理

把普通pojo实例化到spring容器中,相当于配置文件中的 <bean id="" class=""/>
它泛指各种组件,就是说当我们的类不属于各种归类的时候(不属于@Controller、@Services等的时候),我们就可以使用@Component来标注这个类。
此外,被@controller 、@service、@repository 、@component 注解的类,都会把这些类纳入进spring容器中进行管理
复制代码

什么是pojo?POJO详细讲解
POJO实质上可以理解为简单的实体类,顾名思义POJO类的作用是方便程序员使用数据库中的数据表,对于广大的程序员,可以很方便的将POJO类当做对象来进行使用,当然也是可以方便的调用其get,set方法。POJO类也给我们在struts框架中的配置带来了很大的方便。

@Component
public class TestClass {
        public String test(Map<String,Object> map){
            return "hello";
        }
}

@MapperScan

1、@Mapper注解:
作用:在接口类上添加 @Mapper,MyBatis 会在运行时为接口创建代理对象,并交给 Spring 管理。
添加位置:接口类上面

@Mapper
public interface UserDAO {
   //代码
}

如果想要每个接口都要变成实现类,那么需要在每个接口类上加上@Mapper注解,比较麻烦,解决这个问题用@MapperScan

2、@MapperScan
程序会自动为mybatis创建代理对象,这只要把存放所有接口的文件夹路径给他就可以不在接口类上写@Mapper了

作用:指定 Mapper 接口所在的包,包及其子包中的接口会由 MyBatis 创建代理对象并交给 Spring 管理。
添加位置:是在Springboot启动类上面添加,

@SpringBootApplication
@MapperScan("com.winter.dao")
public class SpringbootMybatisDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringbootMybatisDemoApplication.class, args);
    }
}

添加 @MapperScan("com.winter.dao") 后,com.winter.dao 包下的 Mapper 接口就不需要逐个添加 @Mapper

3、使用@MapperScan注解多个包
(实际用的时候根据自己的包路径进行修改)

@SpringBootApplication  
@MapperScan({"com.kfit.demo","com.kfit.user"})  
public class App {  
    public static void main(String[] args) {  
       SpringApplication.run(App.class, args);  
    }  
}  

@SpringBootApplication

用于标识 Spring Boot 应用的启动类。它是以下三个核心注解的组合:

  • @SpringBootConfiguration:标识 Spring Boot 配置类;
  • @EnableAutoConfiguration:根据项目依赖和配置进行自动装配;
  • @ComponentScan:扫描启动类所在包及其子包中的组件。

启动类通常放在项目的根包下,避免扫描范围过小而找不到 Controller、Service 或其他 Bean。

@SpringBootTest

@SpringBootTest 用于加载完整的 Spring Boot 应用上下文,适合集成测试。普通、不依赖 Spring 容器的单元测试不需要使用此注解。


@Lazy

延迟加载:

延迟对象实例的创建,用的时候再去创建


@Scope

单例/多例作用域:

1)@Scope(“singleton”)注解

默认单例作用域,此作用域通常会配合延迟加载使用

2)@Scope(“prototype”) 注解

多例作用域,每次从spring请求类的实例都会创建新的对象,使用完后就销毁了,不会调用销毁方法


@PostConstruct

1)@PostConstruct生命周期初始化注解

​ @PostConstruct,生命周期初始化方法,构造方法之后执行,可以在此方法内部做一些初始化
​ 例如:

@PostConstructpublic void 方法名(){System.out.println("初始化");}

2)@PreDestroy生命周期销毁注解

​ @PreDestroy,生命周期销毁方法,对象销毁之前执行,可以在对象销毁前做一些资源释放操作
​ 例如:

public void 方法名(){System.out.println("销毁");}

@Qualifier

用于区分多个实现类,在项目中由多个实现类时用,通过这个标示,表明了哪个实现类才是我们所需要的 @Qualifier("实现类名")
例如:

  • @Qualifier(“softCache”)

@Repository

此注解一般描述数据逻辑层的具体实现对象,此对象要交给spring管理


@Mapper

描述数据逻辑层接口,告诉Mybatis框架这个接口的实现类,由Mybatis创建,并将其实现类的对象交给spring管理,spring会为他管理的这个bean起个名字,默认为接口名,然后首字母小写。


@DateTimeFormat()

此注解可以自定义日期格式类型,注解写在形参处

例如:@DateTimeFormat(pattern = "yyyy-MM-dd")
如果未指定 pattern,将按 Spring 的默认转换规则处理;实际项目中建议明确指定格式。


@Controller

此注解描述的对象为Controller请求的处理器对象,我们通常称之为handler


@ResponseBody

当使用此注解描述控制层的handler方法时,假如此方法的返回值为map或pojo这样的对象,系统底层会将这样的转换为json格式字符串,然后响应给客户端


@RequestParam

这个注解用于描述方法参数,用于定义参数规则

1)方法参数变量的值,来自哪求参数,例如:@RequestParam("username") //指定网页变量名

2)方法参数变量是否必须传值,例如:@RequestParam(required = true)

3)可以指定方法中的形参必须有客户端的返回值,否则网页报错,例如:@RequestParam


@RequestBody

描述方法参数时,客户端可以以post方式提交json格式的数据


@PathVariable

用于修饰形参(配合@GetMapping注解使用),描述方式参数变量时,表示这个参数的值来自url中{}表达式给的定值

例如:

   @GetMapping("/doParam10/{id}")
   public String doMethodRestUrlParam(@PathVariable Integer id){
        return "request params id's value is"+id;
}

@Value(“${}”)

这个注解就是把容器内的数据获取到类里,${容器内数据的构造},注解修饰变量就可以将容器内的值交给变量存储
例如:容器内数据为

redis:
		host: 192.168.1.1
		
	${}内就写
		${redis.host}就可以获取到数据

@PropertySource

@PropertySource(value = "classpath:路径",encoding = "utf-8")

此注解用来指定程序启动加载指定的配置文件
value = "classpath:路径" 这是.properties文件的根路径,例如:value = "classpath:user.properties"
encoding = "utf-8" 这是.properties文件读取时的编码格式


@Accessors(chain = true)

此注解用于生成支持链式调用的 setter 方法

例如:

User user = new User();
user.setName("A").setAge(11).setSex(0);

@TableName注解

需要MybatisPlus插件,用来修饰POJO类

这个注解就是定义表名与POJO对象名之间的关系

例如:对象名是User,就表示查询的表名为user

也可以指定表名,例如@TableName("user")


@TableId(type = IdType.AUTO)注解

@TableId 用于标记实体类的主键字段,不要求必须同时使用 @TableNametype = IdType.AUTO 表示使用数据库自增主键。


Lombok插件注解

@Data

此注解是Lombok插件注解

此注解描述类的时候,可以自动为函数添加get/set/toString方法


@Slf4j

此注解是Lombok插件注解

发现类上有此注解是,会为此类创建一个日志对象,其对象名为 log

如果不想每次都写private final Logger logger = LoggerFactory.getLogger(当前类名.class); 可以用注解


@AllArgsConstructor

此注解是Lombok插件注解

此注解描述的类为有参构造函数


@NoArgsConstructor

此注解是Lombok插件注解

此注解描述的类为无参构造函数


@Setter / @Getter / @ToString

此注解为Lombok插件注解

可以为类单独设置某种类型


Controller请求系列代码

@RequestMapping(“/”)

@RequestMapping注解描述方法是用于定义请求url到handler中方法的映射

@return view 的名字

个人理解:这就是到时访问网页时的名称,比如括号内些/ABC,到时访问网址就是http://localhost/ABC这样,注意,括号内一定要写斜杠,名称最好和方法名相同

在不是代码类型时使用!


@GetMapping(“/”)

查询应该使用GET

修饰方法为REST风格,URL的定义/path/{var1}/{var2}

例如:@GetMapping("/doParam10/{id}")


@PostMapping(“/”)

增加应该使用POST

可以用来修饰方法为post网页,在客户端访问时可以为括号内的简单名

例如:@PostMapping("/doParam09")

Post向服务器发数据。依照HTTP协议,Post的语义是向服务器添加数据,也就是说按照Post的语义,该操作是会修改服务器上的数据的。

Post请求是不可以被缓存的。对于Post方式提交表单,刷新页面浏览器会弹出提示框 “是否重新提交表单”,Post可以接收二进制等各种数据形式,所以如果要上传文件一般用Post请求。

POST和GET都是向服务器提交数据,并且都会从服务器获取数据。

区别:

1、传送方式:get通过地址栏传输,post通过报文传输。

2、数据位置:GET 参数通常放在 URL 中,会受到浏览器、服务器和网关对 URL 长度的限制;POST 数据通常放在请求体中,但服务器和网关仍可能限制请求体大小。

3、GET和POST还有一个重大区别,简单的说:

不能简单地认为 GET 一定产生一个 TCP 数据包、POST 一定产生两个。数据包数量会受到 HTTP 版本、浏览器实现、连接复用和请求体大小等因素影响。


@DeleteMapping

使用CRUD 删除时,我们应该使用@DeleteMapping标注,


@PutMapping

使用CRUD 修改时,修改应该使用@PutMapping标注


AOP系列注解

@Aspect

注意:需要引入aop的配置文件

注解描述的类为切面对象类型,此切面中可以定义多个切入点和通知方式


@Pointcut

注意:需要配合 @Aspect 注解

注解用于定义切入点

@Pointcut("bean(bean名称)"):bean(bean名称),这个表达式为切入点表达式定义的一种语法,它描述的是某个bean或多个bean中方法的集合为切入点,多个bean写法为@Pointcut("bean(*bean名称)")


@Around()

注解描述的方法,可以在切入点执行之前和之后执行,在当前业务中,此方法为日志通知方法

所有通知中优先级最高的通知,可以在目标方法执行之前,之后灵活进行业务扩展


@Retention()

可以用来修饰注解,是注解的注解,称为元注解

RetentionPolicy.SOURCE:注解只保留在源文件,在java文件被编译为class文件时被遗弃

RetentionPolicy.CLASS:注解被保留在class文件,当jvm加载class文件时被遗弃这是默认的生命周期

RetentionPolicy.RUNTIME:注解被保留在class文件,当jvm加载class文件时任然存在

取值 有效范围
SOURCE 在源文件中有效(即源文件保留)
CLASS 在class文件中有效(即class保留)
RUNTIME 在运行时有效(即运行时保留)

@Target

表示注解的作用范围,一旦超过这个范围,编译就会报错

target通过ElementType来指定作用范围

取值 注解使用范围
TYPE 可用于类或者接口上
FIELD 可用于域上
METHOD 可用于方法上
PARAMETER 可用于参数上
CONSTRUCTOR 可用于构造方法上
LOCAL_VARIABLE 可用于局部变量上
ANNOTATION_TYPE 可用于注解类型上(被interface修饰的类型)
PACKAGE 用于记录java文件的package信息

@Pointcut() 补充

切入点表达式

image.png

针对于Advice通知方法的执行时间的一些注解:

  • @Around 前后都可以执行,注意:有严格顺序要求时使用此注解
  • @Before 目标方法执行之前执行此方法进行功能增强
  • @AfterReturning 目标方法没有出现异常顺利结束时执行它
  • @AfterThrowing 执行目标方法出现异常时执行它
  • @After 不论目标方法是否执行成功我都要执行它进行功能增强,这个方法一般用作资源的释放;

@Before()

AOP的使用方法,表示在目标方法执行之前调用


@AfterReturning()

AOP的使用方法,表示目标方法执行正常结束时调用


@AfterThrowing()

AOP的使用方法,表示目标方法异常结束时执行


@After()

AOP的使用方法,表示目标方法结束时执行


@Documented

Document的英文意思是文档。

它的作用是能够将注解中的元素包含到 Javadoc 中去。

Java 基础注解补充

@Override

用于说明当前方法重写了父类或接口中的方法。重写方法建议始终添加该注解,方法签名写错时编译器会及时提示。

@Override
public String toString() {
    return "User{name='张三'}";
}

@Deprecated

表示类、方法、字段或构造方法已经过时,不建议继续使用。还可以通过 sinceforRemoval 说明废弃版本及是否计划删除。

@Deprecated(since = "2.0", forRemoval = true)
public void oldMethod() {
}

@SuppressWarnings

用于抑制指定的编译器警告,应尽量缩小使用范围,不建议随意使用 all

@SuppressWarnings("unchecked")
public void convert(Object value) {
    List<String> list = (List<String>) value;
}

@FunctionalInterface

表示当前接口是函数式接口,即只包含一个抽象方法,可以配合 Lambda 表达式使用。

@FunctionalInterface
public interface Calculator {
    int calculate(int a, int b);
}

@Inherited / @Repeatable

@Inherited 表示类上的注解可以被子类继承,但不适用于接口、方法和字段。

@Repeatable 表示同一种注解可以在同一个位置重复使用,通常需要提供一个存放注解数组的容器注解。


Spring 核心与配置注解

@Configuration

表示当前类是 Spring 配置类,通常用来声明 @Bean 方法。

@Configuration
public class AppConfig {
    @Bean
    public UserService userService() {
        return new UserService();
    }
}

@ComponentScan

指定 Spring 要扫描的包。扫描到的 @Component@Service@Repository@Controller 等组件会被注册到容器中。@SpringBootApplication 已经包含该注解。

@ComponentScan("com.example")
@Configuration
public class AppConfig {
}

@Import

用于把指定的配置类或组件导入当前 Spring 容器。

@Configuration
@Import({DatabaseConfig.class, CacheConfig.class})
public class AppConfig {
}

@Primary

同一接口存在多个 Bean 时,将其中一个标记为默认选择。注入点使用 @Qualifier 时,优先按 @Qualifier 指定的名称选择。

@Service
@Primary
public class LocalUserService implements UserService {
}

@Resource

Java/Jakarta 提供的依赖注入注解,默认优先按名称匹配,也可以通过 name 指定 Bean 名称。

@Resource(name = "userService")
private UserService userService;

Spring Boot 3 通常使用 jakarta.annotation.Resource


@ConfigurationProperties

把配置文件中具有相同前缀的一组配置绑定到 Java 对象,适合结构化配置。可以通过 @ConfigurationPropertiesScan 扫描,或使用 @EnableConfigurationProperties 注册。

app:
  name: demo
  timeout: 30s
@ConfigurationProperties(prefix = "app")
public class AppProperties {
    private String name;
    private Duration timeout;
    // getter、setter
}

@Profile

指定 Bean 只在某些环境中生效,例如开发、测试或生产环境。

@Configuration
@Profile("dev")
public class DevConfig {
}

可通过 spring.profiles.active=dev 激活环境。


Spring MVC 注解补充

@PatchMapping

用于处理 HTTP PATCH 请求,一般表示对资源进行局部修改。

@PatchMapping("/users/{id}")
public User updatePart(@PathVariable Long id,
                       @RequestBody UserPatchRequest request) {
    return userService.updatePart(id, request);
}

@RequestHeader

获取 HTTP 请求头中的值。

@GetMapping("/header")
public String getHeader(@RequestHeader("User-Agent") String userAgent) {
    return userAgent;
}

如果请求头不是必须的,可以设置 required = false 或指定 defaultValue


@CookieValue

获取请求中 Cookie 的值。

@GetMapping("/cookie")
public String getCookie(@CookieValue(name = "token", required = false) String token) {
    return token;
}

@ModelAttribute

常用于把表单参数绑定到 Java 对象,也可以用于向模型中添加公共数据。

@PostMapping("/users")
public String createUser(@ModelAttribute UserForm form) {
    return "success";
}

@CrossOrigin

用于配置跨域访问,可以写在类或方法上。生产环境中应明确允许的来源,不建议随意使用 origins = "*"

@CrossOrigin(origins = "https://example.com")
@RestController
public class UserController {
}

@ControllerAdvice / @RestControllerAdvice

用于集中处理多个 Controller 的公共逻辑,例如异常处理和参数绑定。@RestControllerAdvice 相当于 @ControllerAdvice + @ResponseBody,通常返回 JSON。

@RestControllerAdvice
public class GlobalExceptionHandler {
}

@ExceptionHandler

用于处理 Controller 中抛出的指定异常,常与 @RestControllerAdvice 配合实现全局异常处理。

@ExceptionHandler(IllegalArgumentException.class)
public Map<String, Object> handleIllegalArgument(IllegalArgumentException exception) {
    return Map.of("message", exception.getMessage());
}

@ResponseStatus

用于指定响应的 HTTP 状态码,可以描述异常类或 Controller 方法。

@ResponseStatus(HttpStatus.NOT_FOUND)
public class UserNotFoundException extends RuntimeException {
}

参数校验注解

Spring Boot 3 使用 Jakarta Validation,对应包名通常为 jakarta.validation.*

@Valid / @Validated

@Valid 用于触发对象参数校验,常与 @RequestBody 配合;@Validated 是 Spring 提供的扩展,支持校验分组,也常用于开启方法参数校验。

@PostMapping("/users")
public void create(@Valid @RequestBody CreateUserRequest request) {
}

@NotNull / @NotEmpty / @NotBlank

  • @NotNull:值不能为 null
  • @NotEmpty:不能为 null,集合、数组或字符串长度必须大于 0;
  • @NotBlank:用于字符串,不能为 null,去除空白后长度必须大于 0。
@NotBlank(message = "用户名不能为空")
private String username;

@Size / @Min / @Max

@Size 限制字符串、集合、Map 或数组的长度;@Min@Max 限制数值范围。

@Size(min = 6, max = 20)
private String password;

@Min(0)
@Max(150)
private Integer age;

小数范围可以使用 @DecimalMin@DecimalMax


@Email / @Pattern

@Email 校验邮箱格式;@Pattern 使用正则表达式校验字符串。

@Email(message = "邮箱格式不正确")
private String email;

@Pattern(regexp = "^1[3-9]\\d{9}$")
private String phone;

事务、异步、定时任务与缓存注解

@Transactional

用于声明事务,可以写在类或方法上。方法正常结束时提交事务,出现满足回滚规则的异常时回滚。

@Transactional(rollbackFor = Exception.class)
public void createOrder(Order order) {
    orderMapper.insert(order);
    stockService.reduce(order.getProductId());
}

同一个类中直接调用带有 @Transactional 的方法,可能绕过 Spring 代理,导致事务不生效;事务通常放在 public 的 Service 方法上。


@EnableAsync / @Async

@EnableAsync 开启异步方法支持,@Async 表示方法在线程池中异步执行。同类内部直接调用也可能绕过代理,使异步失效。

@EnableAsync
@Configuration
public class AsyncConfig {
}

@Async
public CompletableFuture<String> sendEmail() {
    return CompletableFuture.completedFuture("success");
}

@EnableScheduling / @Scheduled

@EnableScheduling 开启定时任务,@Scheduled 定义任务执行规则。

@Scheduled(cron = "0 0 2 * * ?")
public void clearExpiredData() {
}

常用属性:fixedRate 按固定频率执行,fixedDelay 在上一次执行完成后等待指定时间,cron 使用 Cron 表达式。


@EnableCaching / @Cacheable / @CachePut / @CacheEvict

@EnableCaching 开启缓存注解功能。

  • @Cacheable:缓存中没有数据时才执行方法,并缓存返回值;
  • @CachePut:每次执行方法,并用返回值更新缓存;
  • @CacheEvict:删除指定缓存,allEntries = true 表示清空整个缓存区域。
@Cacheable(cacheNames = "users", key = "#id")
public User findById(Long id) {
    return userMapper.selectById(id);
}

MyBatis 与 MyBatis-Plus 注解补充

@Select / @Insert / @Update / @Delete

MyBatis 提供的 SQL 注解,可以直接在 Mapper 接口方法上编写 SQL。简单 SQL 可以使用注解,复杂 SQL 通常更适合放在 XML 中。

@Select("select id, username from user where id = #{id}")
User findById(Long id);

@Param

为 Mapper 方法参数指定在 SQL 中使用的名称。方法有多个参数时建议明确添加。

@Select("select * from user where username = #{name} and status = #{status}")
User find(@Param("name") String username, @Param("status") Integer status);

@TableField

MyBatis-Plus 用于描述实体字段与数据库字段的映射关系,也可以标记某个字段不参与数据库操作。

@TableField("user_name")
private String username;

@TableField(exist = false)
private String displayName;

@TableLogic / @Version

@TableLogic 标记逻辑删除字段;@Version 标记乐观锁版本字段。使用 @Version 前还需要配置 MyBatis-Plus 的乐观锁插件。

@TableLogic
private Integer deleted;

@Version
private Integer version;

Lombok 注解补充

@Builder

生成建造者模式代码,适合参数较多、希望提高创建对象可读性的场景。

@Builder
public class User {
    private Long id;
    private String username;
}

User user = User.builder()
        .id(1L)
        .username("张三")
        .build();

@RequiredArgsConstructor

为所有 final 字段以及带 @NonNull 的字段生成构造方法,Spring 项目中常用它实现构造器注入。

@Service
@RequiredArgsConstructor
public class UserService {
    private final UserMapper userMapper;
}

@Value(Lombok)

这里的 @Value 是 Lombok 注解,不是 Spring 的 @Value。它用于创建不可变类,默认生成 Getter、构造方法、equalshashCodetoString

@Value
public class UserInfo {
    Long id;
    String username;
}

@EqualsAndHashCode / @NonNull

@EqualsAndHashCode 自动生成 equals()hashCode();存在继承关系时要注意 callSuper 的取值。@NonNull 会生成非空检查,参数为 null 时抛出 NullPointerException


Jackson JSON 注解

@JsonProperty / @JsonIgnore

@JsonProperty 指定 Java 属性在 JSON 中的名称;@JsonIgnore 让属性在序列化和反序列化时被忽略。

@JsonProperty("user_name")
private String username;

@JsonIgnore
private String password;

隐藏字段不等于完成安全保护,日志、数据库查询和其他接口仍需单独处理敏感数据。


@JsonFormat / @JsonInclude

@JsonFormat 指定日期时间等数据的 JSON 格式;@JsonInclude 控制哪些值参与 JSON 序列化。

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private LocalDateTime createTime;

@JsonInclude(JsonInclude.Include.NON_NULL)
public class UserResponse {
}

@JsonFormat 影响 JSON 序列化,@DateTimeFormat 主要用于 Spring MVC 请求参数的日期转换,两者用途不同。


JUnit 5 测试注解

@Test

表示当前方法是一个测试方法。

@Test
void shouldAddTwoNumbers() {
    assertEquals(3, 1 + 2);
}

@BeforeEach / @AfterEach

分别在每个测试方法执行前和执行后调用,适合准备和清理测试数据。

@BeforeEach
void setUp() {
}

@AfterEach
void tearDown() {
}

@BeforeAll / @AfterAll

分别在当前测试类的所有测试开始前和结束后执行一次。默认情况下,被注解的方法需要是 static 方法。


@DisplayName / @ParameterizedTest

@DisplayName 为测试类或测试方法设置更容易阅读的名称;@ParameterizedTest 让同一个测试逻辑使用多组参数运行,通常与 @ValueSource@CsvSource@MethodSource 配合。

@ParameterizedTest
@ValueSource(strings = {"admin", "user", "guest"})
void shouldAcceptValidRole(String role) {
    assertNotNull(role);
}
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐