在日常项目开发中,我们经常使用注解,今天我们就按照模块来总结一下常用的注解。
一、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:该注解有两个版本 Junit4 和 Junit5,引入 spring-boot-strater-test 后 Junit4 和 Junit5 同时存在,两者在使用时有所不同,引入的包分别如下:
// 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、hashCode 和 toString 等。该注解可以简化代码。
@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;
}
总结
在日常项目开发中会经常用到文章中提到的注解,熟练掌握这些注解有助于提高开发效率。你掌握了么?
改变你能改变的,接受你不能改变的,关注公众号:程序员康康,一起成长,共同进步。