一、基本注解
1. Lombok
Lombok
为实体类提供一些常用的 get
与 set
方法注解,在使用相关注解前需要引入对应依赖。
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
其常用的注解及其描述参考下表:
注解 | 作用 |
---|---|
@Data | 作用于类上,提供类所有字段的 get 和 set 以及 equals、toString 等方法。 |
@NoArgsConstructor | 作用于类上,无参构造器,为实体类提供无参构造函数。 |
@AllArgsConstructor | 作用于类上,全参构造器,为实体类提供包含全部参数的构造函数。 |
2. 异步注解
(1) @EnableAsync
作用于启动类,项目开启异步调用,通常配合 @Async
使用。
(2) @Async
作用于方法,表示调用该方法的线程与此方法异步执行。通俗的讲,当多线程同时调用多个异步方法,则不同线程之间为交替执行。
3. 缓存注解
常用的缓存注解及其描述信息参考下表:
方法 | 作用 |
---|---|
@EnableCaching | 作用于启动类,用于开启项目缓存,可以配合 Redis 进行使用。 |
@CacheConfig | 作用于实现缓存方法的类上,通过 cacheNames 设置统一前缀。 |
@Cacheable | 根据 Key 读取缓存,若缓存中存在数据则返回缓存数据并跳过方法执行,若缓存中不存在对应数据则继续执行方法并将结果存入缓存。 |
@CacheEvict | 根据 Key 值删除对应缓存。 |
@CachePut | 将方法的返回值存入缓存中,但和 @Cacheable 不同是其在方法执行之前不会进行缓存读取,只是单纯的将每次方法返回值存入缓存中。 |
@Caching | 用于嵌套多种缓存,如同时进行多组缓存写入和删除。 |
上述注解相应的使用示例如下:
@CacheConfig(cacheNames = "users")
public class UserServiceImpl implements UserService {
@Cacheable(key = "#Id")
public User query(String Id) {
return this.userDao.query(Id);
}
@CacheEvict(key = "#user.Id")
public User update(User user) {
return this.userDao.update(user);
}
@CachePut(key = "#Id")
public User query(String Id) {
return this.userDao.query(Id);
}
@Caching(
cacheable = {
@Cacheable(key = "#Id"),
@Cacheable(key = "'list'")
},
evict = {
@CacheEvict(key = "#Id"),
@CacheEvict(key = "'list'")
},
put = {
@CachePut(key = "#Id"),
}
)
public User query(String Id) {
return this.userDao.query(Id);
}
}
二、接口设计
1、路由注解
(1) @Controller
通过视图控制器可以重定向到指定页面。
(2) @RequestMapping
提供路由信息,负责 URL
到 Controller
中的具体函数的映射,常用于页面跳转控制。
@Controller
public class UserController {
/**
* 当访问 localhost:8080/register 时触发
*/
@RequestMapping("/register")
public String toRegister() {
return "register";
}
}
(3) @RestController
@RestController
等价于 @Controller
与 @ResponseBody
的合集,用于标注控制层组件,常配合 @GetMapping
等注解用于接口开发。
@RestController
public class UserController {
/**
* 接口地址 localhost:8080/login
*/
@PostMapping("/login")
public void Login() {
// put content here
}
}
上述示例与下列代码等价,其中 @RequestMapping
也可换成 @GetMapping
等注解。
@Controller
@ResponseBody
public class UserController {
/**
* 接口地址 localhost:8080/login
*/
@RequestMapping("/login")
public void Login() {
// put content here
}
}
2、请求注解
针对 HTTP
的 GET
与 POST
等请求方式, Spring
中提供了一系列对应方式的注解。
注解 | 作用 |
---|---|
@GetMapping | 对应 HTTP 的 GET 请求,获取资源。 |
@PostMapping | 对应 HTTP 的 POST 请求,创建资源。 |
@PutMapping | 对应 HTTP 的 PUT 请求,提交所有资源属性以修改资源。 |
@PatchMapping | 对应 HTTP 的 PATCH 请求,提交资源部分修改的属性。 |
@DeleteMapping | 对应 HTTP 的 DELETE 请求,删除服务器端的资源。 |
3、参数注解
(1) 无注解
当不添加任何注解时,参数是以 Key-Value
形式拼接于请求 Url
中进行接收的,可以传空值或者什么都不传。当添加以下注解时默认参数必填。
(2) @RequestBody
前端以 JSON
对象的数据封装至请求体传输,@RequestBody
可以将其解析为实体对象,传入的对象键名必须和实体类字段名一致。
// 传入的 Json 数据
{
"Id": 1234,
"name": "Alex"
}
// 对应的实体类
public class User {
private String Id;
private String name;
}
// 接口测试类
public class TestController {
@GetMapping("/test")
public User test(@RequestBody User user) {
return user;
}
}
(3) @RequestParam
参数以 Key-Value
形式拼接于请求 Url
中,当传入多个参数时必须使用注解区分,required
用于指定该参数是否必填,默认为 true
。
@GetMapping("/get")
public String demo(// 默认参数必填
@RequestParam(value = "id") String Id,
// 参数非必填
@RequestParam(value = "name", required = false) String name,
// 非必填,为空时默认值为:male
@RequestParam(value = "gender", required = false, defaultValue = "male") String gender) {
return Id + name + gender + "";
}
(4) @PathVariable
获取传入参数至地址栏,假如下面传入的参数为 user
,最终的访问 url
即为:/user
。
@GetMapping("/{path}")
public int Test(@PathVariable String path){
// do something
}
三、项目配置
1. @Service
服务层注解,可以理解就是对 DAO
层进行的再次封装,封装成一个服务以供使用。
当 @Service
没有指定值默认 bean
名称与所实现的接口类一致。
/**
* 等价于 @Service("userService")
*/
@Service
public class UserServiceImpl implements UserService {
}
2. @Mapper
作用于类上,编译后为单独的接口注入容器。
@Mapper
public interface UserMapper {
}
(1) @MapperScan
作用于启动类,当工程中包含多个 Mapper
接口时,每一个都使用 @Mapper
显然过于麻烦。@MapperScan
用于指定 Mapper
所在的包,然后包下面的所有接口在编译之后都会生成相应的实现类。
// 自动扫描包 xyz.ibudai.dao 中带 @Mapper 注解的类
@MapperScan("xyz.ibudai.dao")
public class HealthcareApplication {
public static void main(String[] args) {
SpringApplication.run(HealthcareApplication.class, args);
}
}
3. @Component
标注一个类为 Spring
容器的 Bean
,把 pojo
实例化到 spring
容器中,相当于配置文件中的 bean
注入。
在 Spring
工程中,项目的结构模型可以大致分为以下三类。在具体使用时,若业务场景都并非下述三种,为了区分业务就可以使用 @Component
,但如果你在服务层不使用 @Service
偏要用 @Component
,在代码实现层面没有问题,但为了提高代码可读性及规范化,应尽量避免此类情况。
(Ⅰ) DAO 层
在这层主要负责处理数据库交互等操作,在代码实现上如果使用 JPA
的话即通过 @Repository
实现,若使用 MyBatis
则使用 @Mapper
标识。
(Ⅱ) 服务层
顾名思义,就是为数据提供服务,从数据库读取的数据大部分情况下都很难直接使用,所以这层主要负责将获取的根据需求进行变化,在代码上通常使用 @Service
注解实现。
(Ⅲ) Web 层
这一层就涉及到与前台页面数据交互,通常在该层与前端的数据规范,在代码上使用 @Controller
注解实现。