SpringBoot常用注解
SpringBoot中大量使用来自Spring与SpringMVC的注解,正确且合理的使用注解,可以避免配置繁杂的xml文件,提升开发效率。今天记录一下SpringBoot中经常使用到的注解。
一、路由
正确的路由是进入SpringBoot项目的关键,是打开奇妙之门的钥匙。
[1] RequestMapping
RequestMapping可以作用在Controller上,也可以作用在方法上。若通过http请求访问到getFoodList方法,则需要使用localhost:port/food/list地址。
当然,RequestMapping也有很多变种,比如符合Rest风格的GetMapping、PostMapping、DeleteMapping与PutMapping等。
@RestController
@RequestMapping("/food")
public class FoodController {
@Autowired
FoodService foodService;
@PostMapping("/list")
public List<CategoryFoodListModel> getFoodList(String name) {
return foodService.getFoodList(name);
}
}
二、参数绑定
前端通过json传输请求参数时,使用以下注解可以完成参数的绑定。
[1] PathVariable
当前端将请求地址从/del?picId=1 改成/del/1时,参数不能完成自动绑定,需要使用PathVariable注解。
@DeleteMapping("/del/{picId}")
public Result<Object> delByPicId(@PathVariable Integer picId) {
int affect = picService.delByPicId(picId);
if (affect == 1) {
return Result.success("删除菜品图片成功");
} else {
return Result.fail("删除菜品图片失败");
}
}
[2] RequestBody
用于将Content-Type为application/json类型的数据绑定到特定的对象中。如果前端传入application/json类型数据,而后端又没有用RequestBody进行接收,那么将无法完成参数绑定。
当前端传入Content-Type为application/x-www-form-urlencoded类型的数据时,无需使用任何注解,即可完成参数绑定。
[3] RequestParam
使用RequestParam也可以完成参数的绑定,不过利用其required属性来要求前端传不传。当前端没传时,也可以设置默认值。
该注解只用于变量级别上,不能拥有一个对象上。在大量使用该注解的情况下,或造成参数列表十分冗长的局面。
三、返回JSON
前端希望后端返回JSON格式的数据,需要使用到ResponseBody注解,该注解会将返回的对象自动转化为JSON对象。
如果希望该Controller的方法全部返回JSON,可去掉每个方法的ResponseBody注解,并将Controller改造成RestController,
即RestController=Controller+ResponseBody
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/info/{id}")
@ResponseBody
public UserInfo getUserInfo(@PathVariable Integer id) {
UserInfo userInfo = new UserInfo();
//查询数据库步骤省略
return userInfo;
}
}
四、依赖或属性注入
充分利用Spring的优势,将对象管理交给Spring容器。涉及到的注解有Controller、Service、Component、Configuration、Bean、ComponentScan、MapperScan、Autowired、Value等。
[1] Controller
作用在Controller层,标识该层为控制层
[2] Service
作用在ServiceImpl层,标识该层为Service接口的实现层,即逻辑处理层
[3] Component
可以作用在Util层。在普通的java项目中,工具类中的静态代码块会在类加载时就完成调用。但在SpringBoot项目中,工具类中的静态代码块并不会在类加载时完成调用,此时可在工具类中加入Component注解,将该类纳为容器的管理范围之内,即可解决该问题。
[4] Configuration
作用在配置类中,表明该类为一个配置类。SpringBoot提倡“约定大于配置”,尽量采用java类的配置,而非xml配置。但对于Spring容器管理来说,他们两个其实没有多大区别,最终都要纳入容器的管理范围中。
[5] Bean
一般也是作用在配置类中,一个配置类中往往会有多个方法,每个方法返回不同的配置对象,在该方法头部加入Bean注解,那么配置对象将交由Spring进行管理。此处的Bean注解其实等同于xml标签中的bean。
[6] ComponentScan
以上注解仅仅是标识该类可以交由Spring进行管理,但Spring可能其实不知道他们的存在,需要扫描整个项目类,才能将他们纳入管理中。在SSM项目中,我们会配置Component-scan来完成扫描工作,但在SpringBoot项目中,我们也好像没用过扫描注解啊。原来,在SpringBoot启动类中,SpringBootApplication注解中已经包含了ComponentScan注解,该注解会在启动时自动扫描启动类所在的包,及其子包下的Bean。到这里Spring容器中已经存在了这些Bean了,下一步就是按照某种规则注入到我们所声明的类中。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {...}
[6] MapperScan
MapperScan是MyBatis中的注解,用于扫描dao接口,一般把此注解放在MyBatis的配置类中,MapperScan其中的路径为dao接口所在的包。
@Configuration
@MapperScan("com.yang.plm.dao")
public class MybatisPlusConfig {
/**
* 分页插件
*
* @return PaginationInterceptor
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
paginationInterceptor.setDialectType(DbType.MYSQL.getDb());
return paginationInterceptor;
}
}
[7] Autowired
常常被用于自动导入依赖的Bean。当然也可以使用Resource、Qualifer,其中某些还可以组合使用,达到不同的效果。关于这三个注解的区别,可以参考这篇文章@Resource、@Autowired和@Qualifer三者的区别
[8] Value
在实体类中可以通过此注解获取到application.yml或application.properties中的内容,例如:
@Value("${spring.mail.username}")
private String from;
五、其他功能性注解
[1] ControllerAdvice与ExceptionHandler
这两个注解用于处理全局异常,更详细的介绍可以参考这篇文章全局异常处理与发生异常时的邮件通知
[2] Scheduled
用于标识定时任务,例如:
/**
* 22点进行统计并发送邮件
*/
//秒 分 时 日 月 周
@Scheduled(cron = "0 0 22 * * ?")
public void getCount() {
if (SettingConst.isSendCountMail) {
CountModel countModel = countService.getCount();
sendSimpleMail(countModel);
log.info("{}-定时任务-{}", CountTask.class, "统计并发送邮件");
}
}
值得注意的是,我们需要告诉SpringBoot的启动类,去开启定时任务。很简单,在启动类上面加上EnableScheduling注解。
[3] Transactional
用于某个方法上,标识该方法存在事务处理。在默认配置下,一旦该方法出现异常,则立即回滚所有对数据库的操作。
当然,你还得注意,需要让启动类开启事务支持,只需要添加EnableTransactionManagement注解,其等同于xml配置方式的 <tx:annotation-driven />
当然。盲目的使用注解,会造成大量的注解分散在各个类中,与源代码存在过多的耦合,不好进行统一的维护与管理。此外,修改注解需要重新修改源代码。xml配置虽然冗长,但相比于注解,xml更加集中,修改xml不需要修改源代码,并且拥有更多的灵活性与机动性。
其实,不管是用注解还是xml配置也好,选择一种最简单、最优、最容易理解的方案去解决当下的问题,才是我们真正需要去思考的。