SpringBoot 之常用注解
SpringBoot 之常用注解
在spring boot中,摒弃了spring以往项目中大量繁琐的配置,遵循约定大于配置的原则,通过自身默认配置,极大的降低了项目搭建的复杂度。同样在spring boot中,大量注解的使用,使得代码看起来更加简洁,提高开发的效率。这些注解不光包括spring boot自有,也有一些是继承自spring的。
本文中将spring boot项目中常用的一些核心注解归类总结,并结合实际使用的角度来解释其作用。
说明:本文内容是我从众多博客中查找摘抄的,作为学习笔记,因为链接太多,就不放参考博客链接啦~~~
文章目录
一、SpringBoot 之常用注解
1、@SpringBootApplication
查看源码可发现,
@SpringBootApplication
是一个复合注解,包含了@SpringBootConfiguration
,@EnableAutoConfiguration
,@ComponentScan
这三个注解。
这三个注解的作用分别为:
1.1 @SpringBootConfiguration
标注当前类是配置类,这个注解继承自
@Configuration
。并会将当前类内声明的一个或多个以@Bean
注解标记的方法的实例纳入到srping容器中,并且实例名就是方法名。
1.2 @EnableAutoConfiguration
是自动配置的注解,这个注解会根据我们添加的组件jar来完成一些默认配置,我们做微服时会添加spring-boot-starter-web这个组件jar的pom依赖,这样配置会默认配置springmvc 和tomcat。
1.3 @ComponentScan
扫描当前包及其子包下被
@Component
,@Controller
,@Service
,@Repository
注解标记的类并纳入到spring容器中进行管理。等价于context:component-scan的xml配置文件中的配置项。
大多数情况下,这3个注解会被同时使用,基于最佳实践,这三个注解就被做了包装,成为了@SpringBootApplication注解。
2、@MapperScan
spring-boot支持mybatis组件的一个注解,通过此注解指定mybatis接口类的路径,即可完成对mybatis接口的扫描。
它和
@mapper
注解是一样的作用,不同的地方是扫描入口不一样。@mapper需要加在每一个mapper接口类上面。所以大多数情况下,都是在规划好工程目录之后,通过@MapperScan注解配置路径完成mapper接口的注入。添加mybatis相应组建依赖之后。就可以使用该注解。
3、@Controller
@Controller
表明这个类是一个控制器类,和@RequestMapping
来配合使用拦截请求
,如果不在method中注明请求的方式,默认是拦截get和post请求。这样请求会完成后转向一个视图解析器。但是在大多微服务搭建的时候,前后端会做分离。所以请求后端只关注数据处理,后端返回json数据的话,需要配合@ResponseBody
注解来完成。 这样一个只需要返回数据的接口就需要3个注解来完成,大多情况我们都是需要返回数据。也是基于最佳实践,所以将这三个注解进一步整合。
3.1 @RestController
@RestController
是@Controller
和@ResponseBody
的结合,一个类被加上@RestController 注解,数据接口中就不再需要添加@ResponseBody。更加简洁。 同样的情况,@RequestMapping(value="",method= RequestMethod.GET ),我们都需要明确请求方式。这样的写法又会显得比较繁琐,于是乎就有了如下的几个注解。
普通风格 | Rest风格 |
---|---|
@RequestMapping(value=“”,method = RequestMethod.GET) | @GetMapping(value =“”) |
@RequestMapping(value=“”,method = RequestMethod.POST) | @PostMapping(value =“”) |
@RequestMapping(value=“”,method = RequestMethod.PUT) | @PutMapping(value =“”) |
@RequestMapping(value=“”,method = RequestMethod.DELETE) | @DeleteMapping(value =“”) |
附:@PatchMapping(value =“”)
4、@Autowired
这是个最熟悉的注解,是spring的自动装配,这个个注解可以用到构造器,变量域,方法,注解类型上。当我们需要从bean 工厂中获取一个bean时,Spring会自动为我们装配该bean中标记为@Autowired的元素
@Autowired
是Spring
提供的,默认按照byType
注入,也就是bean的类型的来传入
如果需要指定名字,那么需要使@Qualifier("这是bean的名字")
5、@Resource
@Resource
默认按byName
自动注入,是J2EE
提供的
@Resource有两个中重要的属性:name
和type
,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用 byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。
附:@Resource装配顺序
(1). 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常; (2). 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常; (3). 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常; (4). 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;
@Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入。
6、@EnablCaching
@EnableCaching
: 这个注解是spring framework
中的注解驱动的缓存管理
功能。自spring版本3.1
起加入了该注解。其作用相当于spring配置文件中的cache manager标签。
7、@PathVariable
路径变量注解,
@RequestMapping
中用{ }
来定义url
部分的变量名,参数与大括号里的名字一样要相同,如:
同样可以支持变量名加正则表达式的方式,变量名:[正则表达式]。
8、@RequestParam
获取请求参数的值
@RequestMapping("/getUser")
public String getUser(@RequestParam("uid")Integer id, Model model) {
System.out.println("id:"+id);
return "user";
}
8.1 @PathVariable VS @RequestParam
两者的作用都是将request里的参数的值绑定到contorl里的方法参数里的,区别在于,URL写法不同。
当请求参数username不存在时会有异常发生,可以通过设置属性required=false解决,例如:
@RequestParam(value=“username”,required=false)
使用@RequestParam时,URL是这样的:http://host:port/path?参数名=参数值
使用@PathVariable时,URL是这样的:http://host:port/path/参数值
9、@Service
@Service
:这个注解用来标记业务层的组件,我们会将业务逻辑处理的类都会加上这个注解交给spring容器。事务的切面也会配置在这一层。当让 这个注解不是一定要用。有个泛指组件的注解,当我们不能确定具体作用的时候 可以用泛指组件的注解托付给spring容器
10、@Repository
@Repository
注解类作为DAO对象,管理操作数据库的对象。总得来看,
@Component
,@Service
,@Controller
,@Repository
是spring注解,注解后可以被spring框架所扫描并注入到spring容器来进行管理@Component是通用注解,其他三个注解是这个注解的拓展,并且具有了特定的功能。
通过这些注解的分层管理,就能将
请求处理
,义务逻辑处理
,数据库操作处理
分离出来,为代码解耦,也方便了以后项目的维护和开发。
所以我们在正常开发中,如果能用 @Service, @Controller, @Repository其中一个标注这个类的定位的时候,就不要用@Component来标注。
11、@Component
泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
12、@Transactional
通过这个注解可以声明
事务
,可以添加在类上
或者方法上
。在spring boot中 不用再单独配置事务管理,一般情况是我们会在
servcie层
添加了事务注解,即可开启事务。要注意的是,事务的开启只能在public 方法上
。并且主要事务切面的回滚条件。正常我们配置rollbackfor exception时 ,如果在方法里捕获了异常就会导致事务切面配置的失效。
13、@ConfigurationProperties
Spring Boot将尝试校验外部的配置,默认使用JSR-303(如果在classpath路径中)。
你可以轻松的为你的@ConfigurationProperties类添加JSR-303 javax.validation约束注解:
@Component
@ConfigurationProperties(prefix="connection")
public class ConnectionSettings {
@NotNull
private InetAddress remoteAddress;
// ... getters and setters
}
二、其他注解
1、@JsonIgnore
作用:在实体类向前台返回数据时用来忽略不想传递给前台的属性或接口
Eg:User实体中会有字段password字段,当返回用户信息给前台的时候,当然是不希望将password值也一并返回。所以,这个时候可以在password属性上加上注解JsonIgnore或者,可以在User类上加上注解@JsonIgnoreProperties(value = "{password}")
2、@DateTimeFormat
@DateTimeFormat
是spring
自带的处理框架,主要用于将时间格式化我们可以使用@DateTimeFormat注解将一个字符串转成一个Date对象,pojo类上的哪个Date类型的字段需要,就需要用
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
标记,这样前端页面传递过来的String类型的时间'2016-11-11 11:11:11'
会转换为 Date 类型原因是:页面将数据传到后台,是以字符串的形式。所以时间格式会出错。加上此注解,后台可解析时间格式的字符串。
但需要注意一下事项:
1、如果是
小写的hh
,那个值代表着1-12
比如,我是在下午16:30传入参数的,而小写的h最大只能接受12的值,传入16就出错了,所有无法将String转为Date类型。
2、可以使用在字段上也可以使用在方法中
public String test2(@RequestParam("uid") int id, @DateTimeFormat(pattern="yyyy-MM-dd")Date date, UserInfo user) { //业务逻辑代码...... }
3、@JsonFormat
JsonFormat
来源于jackson
,Jackson是一个简单基于Java应用库,Jackson可以轻松的将Java对象转换成json对象和xml文档,同样也可以将json、xml转换成Java对象。Jackson所依赖的jar包较少,简单易用并且性能也要相对高些,并且Jackson社区相对比较活跃,更新速度也比较快。后台传到前台,前台没办法解析。需要做如下操作:
@JsonFormat(pattern=”yyyy-MM-dd”)
如果直接使用
@JsonFormat(pattern=”yyyy-MM-dd”)
就会出现2018-08-01 08:00:00的情况, 会相差8个小时
,因为我们是东八区(北京时间)。所以我们在格式化的时候要指定时区
(timezone ),如下:@JsonFormat(pattern=”yyyy-MM-dd”,timezone=”GMT+8”)
4、@JSONField
JSONField来源于fastjson,是阿里巴巴的开源框架,主要进行JSON解析和序列化。
我们通常使用json格式在服务器之间进行数据传输。如果json格式数据不符合Java中的标准驼峰式变量定义规则,并且难以理解,这个时候就需要在后台中做二次处理,将数据处理成我们系统中定义的格式。
由于json中的key与bean中的属性不能匹配,通常的转换会出现了部分属性为null的情况。这种情况,我们可以使用@JSONField。
@JSONField的作用对象:
- Field
- Setter 和 Getter方法
注:FastJson在进行操作时,是根据getter和setter的方法进行的,并不是依据Field进行。
代码示例:
@JSONField(name = "reason_clear_time", format = "yyyy-MM-dd HH:mm:ss.S") public void setReasonClearTime(Date reasonClearTime) { this.reasonClearTime = reasonClearTime; }
我们的 POJO 属性字段是reasonClearTime,但是我们需要解析的 json 字符串中的 key 是reason_clear_time, 我们通过使用
@JSONField(name = "reason_clear_time", format = "yyyy-MM-dd HH:mm:ss.S")