常用注解

115 阅读15分钟

在日常项目开发中,我们经常使用注解,今天我们就按照模块来总结一下常用的注解。

一、Web 常用的注解

@Controller: 该注解是 Spring Framework 中的注解,用于标识一个类是控制器组件。

@Controller
public class SysUserController  {
    
}

@RestController:该注解是一个组合注解,相当于 @Controller@ResponseBody的组合,使用在类上,标识该类都默认加上 @ResponseBody

@RestController
public class SysUserController  {
    
}

@RequestMapping:用于 Web 请求,包括访问路径和参数,作用于类或者方法上。

@RestController
@RequestMapping("/sysUser")
public class SysUserController  {
}

@GetMapping:该注解用于 HTTP GET 请求,将请求映射到具体方法中,相当于是 @RequestMapping(method=RequestMethod.GET)的快捷方式。

@RestController
@RequestMapping("/sysUser")
public class SysUserController  {

    @GetMapping("/getUserList")
    public ResponseResult getUserList(Integer pageNum, Integer pageSize, SysUserVO sysUserVO){
        PageDTO userList = sysUserService.getUserList(pageNum, pageSize, sysUserVO);
        return ResponseResult.okResult(userList);
    }
}

@PostMapping:该注解用于 HTTP POST 请求,将请求映射到具体方法中,相当于是@RequestMapping(method=RequestMethod.POST)的快捷方式。

@RestController
@RequestMapping("/sysUser")
public class SysUserController  {

    @PostMapping("/addUser")
    public ResponseResult addUser(@RequestBody SysUser sysUser){
        int count = sysUserService.addUser(sysUser);
        if(count>0){
            return ResponseResult.okResult();
        }else {
            return ResponseResult.errorResult(AppHttpCodeEnum.USER_INSET_ERROR);
        }
    }
}

@PutMapping:该注解用于 HTTP PUT 请求,将请求映射到具体方法中,相当于是@RequestMapping(method=RequestMethod.PUT)的快捷方式。

@RestController
@RequestMapping("/sysUser")
public class SysUserController  {

    @PutMapping("/updateUser")
    public ResponseResult updateUser(@RequestBody SysUser sysUser){
        sysUserService.updateUser(sysUser);
        return ResponseResult.okResult();
    }
}

@DeleteMapping: 该注解用于 HTTP DELETE 请求,将请求映射到具体方法中,相当于是@RequestMapping(method=RequestMethod.DELETE)的快捷方式。

@RestController
@RequestMapping("/sysUser")
public class SysUserController  {

    @DeleteMapping("/deleteUserById/{userId}")
    public ResponseResult deleteUser(@PathVariable("userId") Long userId){
        sysUserService.deleteUser(userId);
        return ResponseResult.okResult();
    }
}

@ResponseBody:该注解会把返回值写入到 HTTP 响应中,@ResponseBody 注解只能用在被@Controller 注解标记的类中。如果在被 @RestController 标记的类中,则方法不需要使用@ResponseBody注解进行标注。

    @ResponseBody
    @DeleteMapping("/deleteUserById/{userId}")
    public ResponseResult deleteUser(@PathVariable("userId") Long userId){
        sysUserService.deleteUser(userId);
        return ResponseResult.okResult();
    }

@RequestBody: 该注解允许将请求参数放在 request 体中,而不是直接连接在地址后面。

@RestController
@RequestMapping("/sysUser")
public class SysUserController  {

    @PutMapping("/updateUser")
    public ResponseResult updateUser(@RequestBody SysUser sysUser){
        sysUserService.updateUser(sysUser);
        return ResponseResult.okResult();
    }
}

@PathVariable: 该注解是将方法中的参数绑定到请求 URL 中的模板变量上,URL中的 {xxx} 占位符可以通过 @PathVariable(“xxx”) 绑定到操作方法的入参中。

    @GetMapping("/getUserById/{userId}")
    public ResponseResult getUserById(@PathVariable("userId") Long userId){
        UserInfoRolePostVO userInfoRolePostVO = sysUserService.getUserById(userId);
        return ResponseResult.okResult(userInfoRolePostVO);
    }

二、容器

@Component: 该注解是 Spring 框架中的注解,用于标记一个类为组件,让Spring 能够在应用程序启动时自动扫描并加载这些组件。

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {

        this.setFieldValByName("createTime", new Date(), metaObject);
        this.setFieldValByName("updateTime", new Date(), metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("updateTime", new Date(), metaObject);
    }
}

@Service:用于标记服务层(Service),告诉 Spring 容器,这个类是一个服务层组件。

@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
}}

@Repository:用于标记持久层(DAO),这是数据库相关的Bean,被标记的类也会被Spring 扫描并自动注入到其他组件中。

import org.springframework.stereotype.Repository;
@Repository
public class UserRepository {
    // Implement your CRUD methods here
}

@Autowired:该注解用于标记Spring要解析和注入的依赖项,可作用于构造函数、字段、setter

# 作用于构造函数
@RestController
@RequestMapping("/sysUser")
public class SysUserController  {
    
    private SysUserService sysUserService;
    @Aurowired
    SysUserController(SysUserService sysUserService){
        this.sysUserService = sysUserService
    }
    @DeleteMapping("/deleteUserById/{userId}")
    public ResponseResult deleteUser(@PathVariable("userId") Long userId){
        sysUserService.deleteUser(userId);
        return ResponseResult.okResult();
    }
}

# 作用于setter方法
@RestController
@RequestMapping("/sysUser")
public class SysUserController  {
    
    private SysUserService sysUserService;
    @Aurowired
    public void SysUserService(SysUserService sysUserService){
        this.sysUserService = sysUserService
    }
    @DeleteMapping("/deleteUserById/{userId}")
    public ResponseResult deleteUser(@PathVariable("userId") Long userId){
        sysUserService.deleteUser(userId);
        return ResponseResult.okResult();
    }
}

# 作用于字段
@RestController
@RequestMapping("/sysUser")
public class SysUserController  {
    
    @Aurowired
    private SysUserService sysUserService;

    @DeleteMapping("/deleteUserById/{userId}")
    public ResponseResult deleteUser(@PathVariable("userId") Long userId){
        sysUserService.deleteUser(userId);
        return ResponseResult.okResult();
    }
}

@Resource:该注解与 @Autowired 注解类似,都用来声明需要自动装配的 Bean,区别在于@Autowired 默认是类型驱动的注入,而 @Resource 默认是名称驱动的注入。可以用在字段、setter方法和构造函数上。

	@Resource(name = "sysUserService")
    private SysUserService sysUserService;

@Qualifier:该注解通常跟 @Autowired 一起使用,当想对注入的过程做更多的控制,@Qualifier 可帮助配置。

// 当一个接口存在多个同名实现类的情况下:
//假设,有两个相同的实现类(不同包),那么可以用name去辨别
@Service("a")
public class SysUserServiceImpl implements SysUserService{
    ......
}

@Service("b")
public class SysUserServiceImpl implements SysUserService{
    ......
}

// 注入的时候配合@Qualifier注解指定名称为a的那个实现类

	@Autowired
    @Qualifier(value = "b")
    private EmployeeService employeeService;

@Configuration:该注解是 Spring 框架中用于定义配置类的注解,被标注的类是一个配置类,(相当于 Spring 配置中的 xml 文件),通常与 @Bean 注解一起使用,用于配置和组装应用程序的组件。配置类可以包含多个被 @Bean 注解标记的方法。

package com.laoxiang.config;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration
public class MybatisPlusConfig {

    /**
     * 3.4.0之后版本
     * @return
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return mybatisPlusInterceptor;
    }
}

@Bean:注解在方法上,声明当前方法的返回值为一个 Bean,这个 Bean 对象交给Spring管理。

package com.laoxiang.config;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration
public class MybatisPlusConfig {

    /**
     * 3.4.0之后版本
     * @return
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return mybatisPlusInterceptor;
    }
}

@Scope:该注解是指采用什么模式去创建 Bean

  • singleton:单实例的(单例模式),全局有且仅有一个实例。
  • prototype:多实例的,每次获取Bean的时候就会有一个新的实例。
  • request:同一请求
  • session:同一会话级别 @Primary:解决多个实现类之间的选择问题,当一个接口有多个实现类时,可以使用 @Primary 注解来指定一个实现类作为首选的候选对象。
@Primary  
@Component  
public class PrimaryServiceImpl implements Service {  
    // 实现细节  
}

@Order:主要控制配置类的加载顺序,设置的值越小越先加载。

@Configuration
@Order(2)
public class TestFilter2 implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("使用@Configration配置过滤器");
        chain.doFilter(request,response);
    }
}

@Profile: 指定组件在哪个环境的情况下才能被注册到容器中。不指定,任何环境下都能注册这个组件。

// 实际使用中,注解中标示了dev、test、uat、prod等多个环境,运行时使用哪个profile由spring.profiles.active控制,以下说明2种方式:配置文件方式、命令行方式

// 在application.properties
spring.profiles.active=dev 
// 在application.yaml
spring:
  profiles:
    active: dev
// 命令行方式
java -jar xxx.jar --spring.profiles.active=dev

三、AOP

AOP相关知识可以参考文章- 《Spring AOP

@Aspect:该注解表示声明一个切面。

  • @After:在方法执行之后执行
  • @Before:在方法执行之前执行
  • @Around:在方法执行之前与之后执行
  • @PointCut:将公共的切点表达式抽取出来,需要用到时引用该切点表达式即可。

@annotation:根据注解匹配

四、事务

事务相关知识可以参考文章《Spring事务

@Transacation:在要开启事务的方法使用该注解,开启声明式事务。

    @Override
    @Transactional
    public void deleteRole(Integer roleId) {
        roleMapper.deleteById(roleId);
        Role roleByRoleId = getRoleByRoleId(roleId);

        userService.deleteUserByRoleId(roleId);
    }

五、异常

@RestControllerAdvice:是一个组合注解,由 @ControllerAdvice、@ResponseBody 组成,而@ControllerAdvice继承了 @Component,因此 @RestControllerAdvice 本质上是个 Component,用于定义 @ExceptionHandler方法。常用于全局异常处理。

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
    
}
@ExceptionHandler:用于标注处理特定类型异常类所抛出异常的方法
    // 全局异常
    @ExceptionHandler(Exception.class)
    public ResponseResult exceptionHandler(Exception e){
        //打印异常信息
        log.error("出现了异常! {}",e);
        //从异常对象中获取提示信息封装返回
        return ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR.getCode(),e.getMessage());
    }

    // 自定义异常
    @ExceptionHandler(LxAdminException.class)
    public ResponseResult LxAdminExceptionHandler(LxAdminException e){
        //打印异常信息
        log.error("出现了异常! {}",e);
        //从异常对象中获取提示信息封装返回
        return ResponseResult.errorResult(e.getCode(),e.getMsg());
    }

六、Json

@JsonIgnore:该注解在 json 序列化时将java bean的一些属性忽略掉,常标记在属性上。

public class  user {
    private  String name;
    @JsonIgnore
    private int age;
}

@JsonIgnoreProperties:json序列化时将java bean中的一些属性忽略掉。标记在类名上

//生成json时将name和age属性过滤
@JsonIgnoreProperties({"name","age"})
public class  user {
    private  String name;
    private int age;
}

@JsonFormat:该注解常用于属性上,把 Date 类转化为想要的模式。

    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;

@JsonInclude:该注解是 jackSon 中最常用的注解之一,是为实体类在接口序列化返回值时增加规则的注解。

@JsonInclude(JsonInclude.Include.NON_NULL)
private String field;

七、异步

@EnableAsync:在配置类或者启动类上注解 @EnableAsync,用于开启异步功能。

@EnableWebMvc
@EnableAsync
@SpringBootApplication()
public class LxadminSystemApplication  {
    
}

@Async:该注解在方法上,用于实现方法的异步:方法调用者立即返回,待调用的方法提交给 Spring的线程池执行。

        @Async("voice")
        public void run(List<VoiceReview>list) {
            
        }

八、定时任务

@EnableScheduling:Spring Framework 提供的一个注解,用于启用 Spring 的定时任务功能。

@EnableScheduling
@EnableWebMvc
@SpringBootApplication()
public class LxadminSystemApplication  {
    
}

@Scheduled:该注解来控制任务在某个指定时间执行,或者每隔一段时间执行。

@Scheduled(cron = "0/4 * * * * ? 2022-2023")
public void test(){
 
    logger.info("输出测试!");
 }

九、测试

@RunWith:表明 Test 测试类要使用注入的类,有了 @RunWith(SpringRunner.class) 这些类才能实例化到 Spring 容器中,自动注入才能生效。

@SpringBootTest
@RunWith(SpringRunner.class)
public class TestAop {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void test1(){
        User user = new User();
        user.setUserName("admin");
        user.setPassword("123456");
        user.setCreateTime(new Date());
        user.setUpdateTime(new Date());

        userMapper.insert(user);
    }
}

@SpringBoot Test:该注解替代了 Spring Test 中的 @ContextConfiguration 注解,目的是加载 ApplicationContext,启动 Spring 容器。

@SpringBootTest
@RunWith(SpringRunner.class)
public class TestAop {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void test1(){
        User user = new User();
        user.setUserName("admin");
        user.setPassword("123456");
        user.setCreateTime(new Date());
        user.setUpdateTime(new Date());

        userMapper.insert(user);
    }
}

@Test:该注解有两个版本 Junit4Junit5,引入 spring-boot-strater-testJunit4Junit5 同时存在,两者在使用时有所不同,引入的包分别如下:

// Junit4
import org.junit.Test
// Junit5
import org.junit.jupiter.api.Test

注意:Junit4 的注解, 则需要加上 @RunWith(SpringRunner.class) 一起使用,如果不加@RunWith注解,Spring 容器不会启动。 @ContextConfiguration:该注解引入多个配置文件。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=UserConfig.class)
public class UserTest {
 
}

十、lombok注解

@AllArgsConstructor:该注解作用在类上,生成一个包含所有参数的构造器。

@AllArgsConstructor
public class User {
    private String userName;
    private String password;
 
}
相当于
public class User {
    private String userName;
    private String password;

    public User (String userName,String password){
        this.userName = userName;
        this.password = password;
    }
}

@NoArgsConstructor:该注解作用在类上,生成一个无参构造器。

NoArgsConstructor
public class User {
    private String userName;
    private String password;
 
}
相当于
public class User {
    private String userName;
    private String password;

    public User (){
        
    }
 
}

@Data:该注解是 Lombok 提供的注解,自动为类生成常用的方法,包括 getter、setter、equals、hashCodetoString 等。该注解可以简化代码。

@Data
public class User {
    private String userName;
    private String password;
 
}
// Lombok 会自动生成以下代码

    public String getUserName() {
        return this.userName;
    }
    
    public void setUserName(String userName) {
        this.userName = userName;
    }
    
    public int getPassword() {
        return this.password;
    }
    
    public void setPassword(String password) {
        this.password = password;
    }
    
    @Override
    public boolean equals(Object obj) {
        // ...
    }
    
    @Override
    public int hashCode() {
        // ...
    }
    
    @Override
    public String toString() {
        // ...
    }
}

@Slf4j:该注解自动生成该类的 log 静态常量,可以直接打印日志,不用手动 new log 静态常量。

@Slf4j
public class User {
    public static void main(string[] args){
        log.info("hello log");
}

// 相当于
public class User {
    private static final Logger log = LoggerFactory.getLogger(User.class);
    public Static void main(string[] args){
        log.info("hello log");
}

@Getter/@Setter:该注解来注释任何字段,以使 Lombok 自动生成默认的getter/setter

@Getter
@Setter
public class User {
    private String userName;
    private String password;
 
}
// 相当于
public class User {
    private String userName;
    private String password;

    
    public String getUserName() {
        return this.userName;
    }
    
    public void setUserName(String userName) {
        this.userName = userName;
    }
    
    public int getPassword() {
        return this.password;
    }
    
    public void setPassword(String password) {
        this.password = password;
    }
}

@ToString:该注解生成 toString,默认情况下会打印类名以及每个字段。

@ToString
public class User {
    private String userName;
    private String password;
 
}

// 相当于
public class User {
    private String userName;
    private String password;

    public String toString(){
        return "User(userName=" + this.userName + ",password=" + this.password +")";
 
}

十一、Swagger

@Api:该注解用于标注一个 Controller 类,在默认情况下,Swagger-Core 只会扫描解析具有@Api 注解的类。

@RestController
@RequestMapping("/sysUser")
@Api(tags = "用户管理")
public class SysUserController  {
    
}

@ApiOperation:该注解用于对一个操作或者 http 方法的描述,具有相同路径的不同操作会被归组为同一个操作对象。

    @ApiOperation(httpMethod = "GET", value = "用户列表")
    @GetMapping("/getUserList")
    public ResponseResult getUserList(Integer pageNum, Integer pageSize, SysUserVO sysUserVO){
        PageDTO userList = sysUserService.getUserList(pageNum, pageSize, sysUserVO);
        return ResponseResult.okResult(userList);
    }

@ApiParam:该注解作用于请求方法上,定义 api 参数。

public ResponseResult getUserById(
      @ApiParam(value = "用户id", allowableValues = "range[1,10]", required = true)
      @PathVariable("UserId") Long userId)

@ApiImplicitParams/@ApiImplicitParam:都可以定义参数

@ApiImplicitParams:作用于方法上,包含一组参数说明。

@ApiImplicitParam:对单个参数的说明

@ApiImplicitParams({
        //参数效验
		@ApiImplicitParam(name="phonenum",value="手机号",required=true,paramType="form"),
		@ApiImplicitParam(name="password",value="密码",required=true,paramType="form"),
		@ApiImplicitParam(name="age",value="年龄",required=true,paramType="form",dataType="Integer")
	})
	@PostMapping("/login")
	public ResponseResult login(@RequestParam String phonenum, @RequestParam String password,
	@RequestParam Integer age){
		//...
	    return ResponseResult.ok();
	}

@ApiResponses/@ApiResponse:方法返回对象的说明。

    @ApiOperation(httpMethod = "GET", value = "用户列表")
    @GetMapping("/getUserList")
    @ApiResponses({
            @ApiResponse(code = 200, message = "请求成功"),
            @ApiResponse(code = 401, message = "没有访问权限"),
            @ApiResponse(code = 403, message = "资源不可用"),
            @ApiResponse(code = 404, message = "地址输入有误"),
    })
    public ResponseResult getUserList(Integer pageNum, Integer pageSize, SysUserVO sysUserVO){
        PageDTO userList = sysUserService.getUserList(pageNum, pageSize, sysUserVO);
        return ResponseResult.okResult(userList);
    }

@ApiModel:该注解用于描述一个 model 信息

@ApiModelProperty:用于描述一个 model 的属性

@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("sys_user")
@ApiModel(value = "SysUser对象", description = "用户信息表")
public class SysUser  implements Serializable{
    private static final long serialVersionUID = 767991252105621235L;

    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    @ApiModelProperty("部门ID")
    @TableField("dept_id")
    private Long deptId;

    @ApiModelProperty("用户名")
    @TableField("user_name")
    private String userName;
}

总结

在日常项目开发中会经常用到文章中提到的注解,熟练掌握这些注解有助于提高开发效率。你掌握了么?


改变你能改变的,接受你不能改变的,关注公众号:程序员康康,一起成长,共同进步。