Java学习中,注解是不可或缺的,有些可以简化代码,有些可以使用功能,下面一一讲解常用的注解。
开始之前,首先在IntelliJ IDEA中安装Lombok插件。
在pom.xml中添加依赖:
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
1 @Slf4j
常用的日志类,相比log4j,多了占位符。在application.yml中配置保存路径 log.addr: /startup-log。
配置不同级别,清除日期,总保存量等。
导入包:
import lombok.extern.slf4j.Slf4j;
控制器在类前加@Slf4j就可以使用,在代码中打印传参等调试信息。
@Slf4j //lombok注解,注入log对象,在代码中直接使用"log"打印日志
public class UserController {
Result getUsers(@RequestParam(value = "pageNumber") Integer pageNumber,
@RequestParam(value = "pageSize") Integer pageSize){
log.info("查询User,第{}页,每页{}条", pageNumber, pageSize);
}
}
调用 http://localhost:19999/users?pageNumber=1&pageSize=5,在startup-log中打开info.log
2022-11-07 16:24:05.432 [INFO ] com.jch.controller.UserController.getUsers(UserController.java:26) 查询User,第1页,每页5条
2 @RestController
@ResponseBody //返回数据为json格式
相当于在每个方法前加@ResponseBody,表示返回值为json或xml格式写入http response body,而不是跳转 jsp 页面,通常作为接口使用。
3 @Autowired / @Resource/ @Service
导入包:
import org.springframework.beans.factory.annotation.Autowired;
在容器中查询对应 类型 的bean,如果查询结果刚好为一个,就将该bean装配给指定的属性,
如果查询的结果不止一个,那么根据名称来查找。如果查询的结果为空,那么会抛出异常。
@Autowired
private SbUserService sbu;
@Service
public class SbUserService{}
配合@Service 自动注入到spring容器中,这样就把 public class SbUserService 类装配给 sbu 属性,
相当于:
private SbUserService sbu = new SbUserService();
@Resource 用法和 @Autowired 差不多,区别在于按照名称进行装配。
4 @GetMapping @PostMapping @DeleteMapping @PutMapping
Restful规范,表示使用get/post/delete/put方式调用传参。
@GetMapping("/users/{userId}")
按照id获取数据,访问 http://localhost:18888/users/1
5 @Data
import lombok.Data;
相当于注解包含了@Getter、@Setter、@ToString、@EqualsAndHashCode、@RequiredArgsConstructor等。自动生成属性的 getter setter等方法,配合Lombok使用。
@Data
public class SbUser implements Serializable {
private Integer id;
private String name;
}
可以直接使用,简化代码。
SbUser sbUser = new SbUser();
sbUser.setName("jch");
6 @RestControllerAdvice / @ExceptionHandler
导入包:
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
配合@ExceptionHandler使用,用于拦截异常并处理返回值为自定义格式。
定义错误码:
public enum CodeMsg {
ERR001("001","参数异常");
private String code;
private String message;
CodeMsg(String code, String message) {
this.code = code;
this.message = message;
}
public String getCode() {
return code;
}
public String getMessage() {
return message;
}
}
自定义异常类:
public class MyException extends RuntimeException {
private String code;
public MyException(CodeMsg codeMsg) {
super(codeMsg.getMessage());
this.code = codeMsg.getCode();
}
}
全局异常处理类:
@RestControllerAdvice
public class ErrorHandler {
@ExceptionHandler(MyException.class)
public Object handleException(MyException e) {
log.error("请求失败,异常信息:", e);
return Result.fail(e.getCode(),e.getMessage());
}
}
在代码中抛出 MyException 异常,将由 ErrorHandler 统一处理成消息返回给客户端。
throw new MyException(CodeMsg.ERR001);
接口返回值:
//com.jch.error.MyException: 参数异常
{“code”:“001”,“message”:“参数异常”,“result”:null}
7 @Transactional
指定事务回滚方式,因为Spring默认只对编译时异常回滚,而对运行时异常不会回滚。
@Transactional(rollbackFor = Exception.class)
public Integer addUser(AUUserReq req) {
SbUser sbUser = new SbUser();
sbUser.setName(req.getName());
sbUser.setAge(req.getAge());
this.insertSelective(sbUser);
UserDetail userDetail = new UserDetail();
userDetail.setUserId(sbUser.getId());
userDetail.setJob(req.getJob());
userDetailService.insertSelective(userDetail);
return sbUser.getId();
}
在有操作多表方法前添加,可以保证数据一致性。
8 @SpringBootTest / @Test
测试使用类
@SpringBootTest
class StartupApplicationTests {
@Autowired
private SbUserService sbu;
@Test
void insertUser(){
SbUser sbUser = new SbUser();
sbUser.setName("jch");
sbUser.setAge(31);
sbu.insert(sbUser);
}
}