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用于注解通用性强的工具类(会被多方调用)。
例如:
-
既被控制器调用,又被服务实现类调用的类
-
被多个控制器/服务实现类调用的类
@Autowired
@Autowired用来获取bean。
在SpringBoot中,默认的匹配方式是byType,具体规则如下:
-
按照类型去容器找到对应的组件
如果找到:赋值
如果没找到:报异常
如果找到多个:使用变量名作ID匹配,匹配上就赋值,没有就报错。
这里说明一下:ID即为类名的首字母小写,例如UserServiceImpl类的ID就是userServiceImpl
-
可以使用@Qualifier注解指定ID
例子:
-
使用变量名作ID匹配
@Autowired
private UserService userService;
查找到多个相同的类:UserService(id = userService)及其子类UserServiceExtend(id = userServiceExtend)
这时,使用userService作id匹配到UserService类。
-
使用@Qualifier指定id
@Autowired
@Qualfier("adminServiceImpl")
private UserService userService; // private UserService userService = new AdminServiceImpl();
...
...
public class AdminServiceImpl implements UserService{
...
}
-
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;
一般只有一些账户密码数据需要使用该功能。
常用注解到这里就介绍完了,最后说一句,实操才是硬道理,要多练!