Spring常用注解

 

Spring常用注解

本文枚举一些常用的SpringBoot开发注解,希望能帮助读者在SpringBoot开发中正确地使用注解。

@Spring Application

主程序注解,spring框架的main函数自带注解。一般不需要开发人员操作,Spring Initializer会写好。

@Controller

标注控制器类,控制器中的方法可以返回一个视图,在Web开发中一般使用的少(主要是用@RestController)。

@ResponseBody

@Controller+@ResponseBody=@RestController

因为SpringBoot已经封装了@RestController,所以一般不需要使用上面等式左边的方式(好比茴字的四种写法),我个人认为不需要花时间学习。

@RequestBody

@PostMapping中会再次介绍。将json解析为java对象。

使用场景:json传参

@RequestMapping

@RequestMapping(“url“),用来将请求映射到方法。

在实际开发中,在具体的控制器类之前添加该注解即可。

@RequestParam

用来获取url中?后的参数。

public void searchById(@RequestParam(value ="id", required = true, defaultValue = "0")int id){
// required, defaultValue不写也可以
...
}

使用场景:URL传参

@PathVariable

同样是从URL中获得参数,方式和@RequestParam不一样。

@RequestMapping("/user/{id}")
public void searchById(@PathVariable(required = true)int id){
...
}

使用场景:URL传参

@RestController

作用=@Controller+@ResponseBody,返回json格式数据。现在Web开发中的Controller一般都是RestController。

一般和@RequestMapping、@GetMapping、@PostMapping配合使用。

使用方法:

@RequestController
public class RestController {
...
}

@GetMapping

响应GET请求。

@RequestController
@RequestMapping("rest")
public class RestController {
 @GetMapping("get") // http://localhost:8080/rest/get
 public String get(){
   return "";
}
}

@GetMapping可以使用@PathVariable、@RequestParam

@PostMapping

响应POST请求。

@RequestController
@RequestMapping("rest")
public class RestController {
 @PostMapping("post") // http://localhost:8080/rest/post
 public String post(@RequestBody User user){
   return "";
}
}

一般来说,POST方法的传参不受限制,可以使用URL传参,也可以使用@RequestBody获取请求体中的json,并解析为响应的java对象。

POST方法和GET方法可以共用一个URL,不用担心起冲突,即下面的使用方式是OK的:

@RequestController
@RequestMapping("rest")
public class RestController {
 @GetMapping
 public String get(){
   return "";
}
 @PostMapping
 public String post(@RequestBody User user){
   return user.toString();
}
}
// 不会冲突,只要请求方法正确(正确使用GET、POST),就能被正确的方法响应。

@PutMapping、@DeleteMapping使用方式大同小异,其实从功能上来说,@PostMapping能替代所有的请求,但是这么使用会导致代码语义混乱

简单说明一下各种请求方法的使用场景:

方法 场景
GET 获取资源
POST 新增资源
PUT 更新资源
DELETE 删除资源

@CrossOrigin

用来解决跨域问题,何为跨域移步这里

在Blog中,博主给了跨域的详细例子:

当前页面url 被请求页面url 是否跨域 原因
http://www.test.com/ http://www.test.com/index.html 同源(协议、域名、端口号相同)
http://www.test.com/ https://www.test.com/index.html 跨域 协议不同(http/https)
http://www.test.com/ http://www.baidu.com/ 跨域 主域名不同(test/baidu)
http://www.test.com/ http://blog.test.com/ 跨域 子域名不同(www/blog)
http://www.test.com:8080/ http://www.test.com:7001/ 跨域 端口号不同(8080/7001)

(上表来自链接博文)

关于AJAX跨域问题移步这里

@RequestController
@RequestMapping("rest")
public class RestController {
 @PostMapping
 @CrossOrigin
 public String post(@RequestBody User user){
   return user.toString();
}
}
//跨域问题解决

@Service

Controller中一般是不写逻辑的,都是直接调用相应的服务,我们需要吧业务逻辑封装在服务中。

上面的例子只是为了方便才把逻辑写入控制器,实际开发中不要图这种方便。

@Service用来注册bean,要放在服务的实现类之前。

接下来使用UserService做例子。这是一个接口。

// 接口类
public class UserService {
 public ResponseVO addUser(User user);
}
// 实现类

@Service // 一定是在实现类而非接口类中
public class UserServiceImpl implements UserService {
 
public ResponseVO addUser(User user){
   // implement the interface
}
}
// 控制器类
public class UserController {
 @Autowired
 private UserService userService;
}

一般在控制器类中,又一个Service成员,在这个例子中便是private UserService userService

我们当然可以选择:

private UserService userService = new UserServiceImpl();

但是SpringBoot提供了更方便的做法:

@Autowired
private UserService userService;

只要实现类被正确的标注,那么@Autowired就能帮我们完成初始化任务。

关于Autowired的进一步介绍移步@Autowired

@Component

@Component和@Service非常类似,同样用来注册bean,使用方式也是一样的,区别在二者的使用场景。

@Service用于注解业务逻辑层中的服务代码,@Component用于注解通用性强的工具类(会被多方调用)。

例如:

  1. 既被控制器调用,又被服务实现类调用的类

  2. 被多个控制器/服务实现类调用的类

@Autowired

@Autowired用来获取bean。

在SpringBoot中,默认的匹配方式是byType,具体规则如下:

  1. 按照类型去容器找到对应的组件

    如果找到:赋值

    如果没找到:报异常

    如果找到多个:使用变量名作ID匹配,匹配上就赋值,没有就报错。

    这里说明一下:ID即为类名的首字母小写,例如UserServiceImpl类的ID就是userServiceImpl

  2. 可以使用@Qualifier注解指定ID

例子:

  1. 使用变量名作ID匹配

@Autowired
private UserService userService;

查找到多个相同的类:UserService(id = userService)及其子类UserServiceExtend(id = userServiceExtend)

这时,使用userService作id匹配到UserService类。

  1. 使用@Qualifier指定id

@Autowired
@Qualfier("adminServiceImpl")
private UserService userService; // private UserService userService = new AdminServiceImpl();
...

...
public class AdminServiceImpl implements UserService{
...
}
  1. required=false

    @Autowired是默认required=true的,设为false找不到就不会报错,而是置为null。

@Resource

没有@Autowired的按类匹配机制,但是可以指定name

@Resource(adminServiceImpl)
private UserService adminService;
...

public class AdminServiceImpl implements UserService{
...
}

功能基本被@Autowired覆盖。

@Resource(name = id) = @Qualifier(id) + @Autowired

除了利用上面这个等式缩减代码,我想不到别的使用场景。

@Configuration + @Beans

这俩是一起使用的,可以人为注册Bean,替代@Service和@Component

@Configuration
public class Beans{
 @Bean
 public UserService userServiceImpl(){
   return new UserServiceImpl();
}
 @Bean
 public UserService adminServiceImpl(){
   return new AdminServiceImpl();
}
}

// UserController.java
@Resource(name=adminServiceImpl)
private UserService adminService;

@Resource(name=userServiceImpl)
private UserService userService;

说实话比较鸡肋的功能......反正了解就好。

@Value

还差一口气就看完了。

@Value用来从配置文件(.properties/.yaml/.yml)中取参数。

例如:

# application.properties

local.name = crx
@Value("${local.name}")
private String author;

一般只有一些账户密码数据需要使用该功能。

 

常用注解到这里就介绍完了,最后说一句,实操才是硬道理,要多练!

上一篇:@AllArgsConstructor


下一篇:为什么Java byte 类型的取值范围是-128~127 (转)