1、@Slf4j
由lombok提供的增删组件。
用法:
打在类上面,就可以直接用log.info("**")打日志
@Slf4j class Test { public void method() { log.info("打印日志") } }
需要注意的是 log 是 private static final 定义的,所以父类中定义了log,子类中是拿不到的,如果想在子类中也能拿到。去掉类上面的@Slf4j,改成在类内定义
class Test { protected Logger log = LoggerFactory.getLogger(this.getClass()); public void method() { log.info("打印日志") } }
这样定义不仅能让子类拿到 log ,还能对应到子类的类名(this.getClass())。
2、@RestController
相当于Controller+ResponseBody
用法:加在controller上面,下面的方法就不用每次都加上@ResponseBody
@RestController class Test { }
3、@RequestMapping
用来映射请求,主要通过它来指定控制器可以处理哪些URL请求,还可以配置别的性质
path
请求路径=类上面的path+方法上的path
path 中还可以放路径的数组(使用的比较少,常用在调用老接口)
@RequestMapping(path={"/acti/manage","/acti/manage1"}) class Test { @GetMapping(path="supplier") public method(){ } }
真实的请求路径为 /acti/manage/supplier,或/acti/manage1/supplier
method
用来指定处理哪些http请求方式,可支持一个或多个请求方式,一般不放在类上,放在具体的方法上
如果不写method时 是默认支持get与post
@RequestMapping("/request_method") @Controller public class RequestMethodController { @RequestMapping(value="/test1",method={RequestMethod.POST,RequestMethod.GET}) //请求方式post和get public void test1() { } @RequestMapping(value="/register",method={RequestMethod.GET}) //默认请求方式是get public void test2() { } @RequestMapping(value="/register",method={RequestMethod.POST}) //请求方式post public void test3() { } }
params、headers、consumes
他们都是为请求做过滤的,并且用法相似
-
params 用来指定要处理 参数为特定值的请求
@RequestMapping(path = "/acti/manage", params = "a=1" ) class Test { @GetMapping(path="supplier") public method(){ } }
表示只处理这个路径来的且参数a=1的那些请求
-
headers 用来处理http请求的header中参数为特定值的请求
@RequestMapping(path = "/acti/manage", headers = "x-version=CORE-939" ) class Test { @GetMapping(path="supplier") public method(){ } }
表示只处理这个路径来的且请求头中x-version=CORE-939的那些请求
可以用在接口的版本升级时,保证老接口的逻辑不动。
-
consumes 用来处理请求头中Content-Type等于某些特定值的那些请求
@RequestMapping(path = "/acti/manage", headers = "Content-Type=application/json", consumes = "MediaType.APPLICATION_JSON_UTF8_VALUE" ) class Test { @GetMapping(path="supplier") public method(){ } }
consumes = "MediaType.APPLICATION_JSON_UTF8_VALUE" 等价于 headers = "Content-Type=application/json"
consumes还有另外一个作用:指定请求的时候用什么格式来解析数据
public void method(@RequestBody ManageCouponVo vo){ }
方法中的@RequestBody 会将传进来的字节流(或字符串)信息解析成特定的Vo对象,而传入的字节流具体什么格式来解析(json,xml,form),也是通过consumes 来规定的
@RequestMapping(path = "/acti/manage", headers = "Content-Type=application/json", consumes = "MediaType.APPLICATION_XML_VALUE" ) class Test { @GetMapping(path="supplier") public void method(@RequestBody ManageCouponVo vo){ } }
上面这个就是就传来的RequestBody解析按照XML格式来解析
@RequestMapping(path = "/acti/manage", headers = "Content-Type=application/json", consumes = "MediaType.APPLICATION_FORM_URLENCOOED_VALUE" ) class Test { @GetMapping(path="supplier") public void method(@RequestBody ManageCouponVo vo){ } }
这个是按照FROM格式解析比较特殊,不是从RequestBody来解析的,而是从RequestParams拿
-
produce 与consumes正好相反,consumes是规定请求时按什么格式来解析,而produce 是规定响应时按什么格式解析
@RequestMapping(path = "/acti/manage", headers = "Content-Type=application/json", consumes = "MediaType.APPLICATION_JSON_UTF8_VALUE", produce = "MediaType.APPLICATION_JSON_UTF8_VALUE" ) class Test { @GetMapping(path="supplier") public void method(@RequestBody ManageCouponVo vo){ } }
上面这个是规定响应时按json格式
produce = "MediaType.APPLICATION_JSON_UTF8_VALUE" //响应时按json格式 produce = "MediaType.TEXT_PLAIN-VALUE" //返回原生的字符串 produce = "MediaType.TEXT_HTML-VALUE" //返回html页面
4、@Validated
包括@Valid,都是用来做校验的。
@Validated加在类上面。@Valid加在方法参数前面。两个至少有一个要写,如果都不写,即使Vo有规则定义,也不会生效
二者不会冲突,只能说是重复(@Validated由springframework提供,@Valid由javax提供),功能上来说一样。
@Validated class Test { @GetMapping(path="supplier") public void method(@Valid @RequestBody ManageCouponVo vo){ //校验的规则在后面的Vo中定义 } }
@NotNull、@NotBlank、@NotEmpty
@NotNull //适用于基本数据类型(Integer,Long,Double等等),当 @NotNull 注解被使用在 String 类型的数据上,则表示该数据不能为 Null(但是可以为 Empty) @NotBlank //适用于 String 类型的数据上,加了@NotBlank 注解的参数不能为 Null 且 trim() 之后 size > 0 @NotEmpty //适用于 String、Collection集合、Map、Array数组等等,加了@NotEmpty 注解的参数不能为 Null 或者 长度为 0 1.String name = null; @NotNull: false @NotEmpty:false @NotBlank:false 2.String name = ""; @NotNull:true @NotEmpty: false @NotBlank: false 3.String name = " "; @NotNull: true @NotEmpty: true @NotBlank: false
1.@NotNull:不能为null,但可以为empty (""," "," ")
2.@NotEmpty:不能为null,而且长度必须大于0 (" "," ")
3.@NotBlank:只能作用在String上,不能为null,而且调用trim()后,长度必须大于0 ("test") 即:必须有实际字符
@Max
@Max //被注释的元素必须是一个数字,其值必须大于等于指定的最大值
支持BigDecimal、BigInteger、byte、short、int、long以及他们的反射。不支持double、float、String,如果是null,会认为是通过校验的。
子类覆盖父类的校验规则
因为子类不能覆盖父类的字段,所以校验的注释打在get,set方法上
5、JSON的序列化和反序列化
@JsonFormat
(加在字段上)时间格式化注解,使用pattern 自定义转化的格式,timezone 设定时区
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT-8") private LocalDateTime limitApplyDate;
@JsonIgnore
(加在字段上)不参与序列化和反序列化
@JsonIgnore
@JsonGetter
(加在Get方法上),只参与序列化。
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT-8") private LocalDateTime limitApplyDate; @JsonGetter public LocalDateTime getDate() { return limitApplyDate; }
@JsonSetter
同理
@JsonView
在使用不同的接口方法有时返回同一个对象,而我们希望这个对象返回不同的字段。
@GetMapping(path="supplier1/{userId}") @JsonView(ListView.class) public UserVo method1(){ // 返回的对象包含 多个字段 } @GetMapping(path="supplier2/{userId}") @JsonView(SingleView.class) public UserVo method2(){ // 返回的对象包含 单个字段 }
至于哪些字段在哪个接口方法返回,同样在该字段上加上对应的@JsonView
6、url参数的接收
@PathVariable
将url中的参数直接拿下来赋值给@PathVariable后面的形参,如果二者命名不一致,则需要明确(name="code")。
@Validated class Test { @GetMapping(path="supplier/{code}") public void method(@Valid @RequestBody ManageCouponVo vo, @PathVariable(name="code") String activityCode){ //校验的规则在后面的Vo中定义 } }
@PathVariable的required属性,默认是required=true(是指url的参数必填)。但是如果设置了required=false(试图处理这个路径下没参数的请求)。这里就得注意
错误:
@Validated class Test { @GetMapping(path="supplier/{code}") public void method(@Valid @RequestBody ManageCouponVo vo, @PathVariable(name="code",required=false) String activityCode){ //校验的规则在后面的Vo中定义 } }
如果就i加上required=false是会报错的。因为带url和不带url是两种不同的请求路径,所以都得写上
@Validated class Test { @GetMapping(path={"supplier/{code}","supplier"}) public void method(@Valid @RequestBody ManageCouponVo vo, @PathVariable(name="code",required=false) String activityCode){ //校验的规则在后面的Vo中定义 } }
@RequestParam
与@PathVariable类似,都有各种属性
@GetMapping(path="supplier/{userId}") public void method(@RequestParam(name = "userId",defaultValue = "常量") String uid ){ }
不同的是,需要加属性,defaultValue = "常量"。@RequestParam只能在方法的参数上配置
如果接收的参数多,那就先定义一个对象类,字段名就是传过来的各种参数
@Getter @Setter public class ManageVo { private String code; private String code2; private String code3; // 如果在这里定义一个对象 // 那么接收参数的形式必须是:inner.a=1,inner.b=2 private Map<String,String> inner; }
二者的区别
-
@PathVariable 翻译过来是 “路径变量的意思” ,顾名思义只能接收 url 路径后面跟着的参数 比如 @GetMapping("/books/{username}") 里的username
-
@RequestParam 翻译过来是 “请求参数的意思” ,顾名思义接收的是请求带过来的参数, 也就是普通参数 , 比如 @GetMapping("/books?username=“张三”) 里的username
PathVariable一般用于get和delete请求,RequestParam一般用于post请求接收请求体中的参数
7、Bean的注入
@Resource
@Resource默认按 byName自动注入,也可以按byType按类型自动注入。要注入的Bean必须存在(因为@Resource不像@Autowired一样有required属性)
@Resource (name= "baseDao" ) private BaseDao baseDao;
@Resource装配顺序
-
如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
-
如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
-
如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
-
如果既没有指定name,又没有指定type,则自动按照”变量名“进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配
-
-
@Autowired
@Autowired默认按类型装配,默认情况下必须要求依赖对象必须存在(required=true),也就是说要注入的这个Bean必须存在。
如果可能不存在,还不报错就需要设置@Autowired(required=false)。
(这个只是解决方案,但是不太明白到底为什么要初始化的这个Bean不存在)
@Autowired private BaseDao baseDao
此外,也可以按名称注入,需要额外用到@Qualifier
@Autowired @Qualifier("baseDao") private BaseDao baseDao
特殊用法—加载该Bean所有实现类
@Autowired private Collection<BaseDao> bizs // private Map<String,BaseDao> bizs String指小写实现的类名
二者的区别
-
主要:@Resource默认按名称装配,@Autowired默认按类型
-
@Resource是javax包下的,@Autowired是springframework包下的
-
@Resource可以在(类、字段、方法)上写,@Autowired可以在(字段、set方法、方法的参数中)上写。
这里说到set方法上加注解注入,用这种注入主要为了方便子类的重写(因为子类可能需要主要不一样的Bean,那时候如果注入加在字段上,就改不了了。但是加在方法上就可以重写,来改变参数)
private BaseDao baseDao; @Resource // 或@Autowired public void setBaseDao(BaseDao baseDao) { this.baseDao = baseDao }
二者处理多个实现类
-
@Resource最为实用:在每个实现类上都加上@Service("XXX"),对每个实现类进行命名。随后需要注入哪个实现类,按名称注入就行。
-
@Autowired有两个方法,都比较麻烦
-
加@Qualifier,变成按名称注入,实现方式同@Resource
-
在需要注入的那个实现类上加@Priamry,就可以当多个实现类之中默认注入该实现类,多用在Dispatch实现类上
-
-
@Autowired也有独特的用处,就是它可以加在方法的参数中,具体体现在当实现带参构造方法时,参数只能用@Autowired和@Qualifier来注入
public class Test { protected BizService<T> bizNode; public Test(BizService<T> bizNode) { // 单参数的构造,给子类调用 this.bizNode = bizNode } @Autowired // 在这里加了@Autowired,而在上面的构造没加,是因为Test类初始化时,因为有个构造,得有一个默认的构造 public Test( // 方法的参数只有@Autowired能使用 @Qualifier(name = "BizServiceImpl1") BizService<T> BizServiceImpl1, @Qualifier(name = "BizServiceImpl2") BizService<T> BizServiceImpl2, @Qualifier(name = "BizServiceImpl3") BizService<T> BizServiceImpl3,) { } }
8、@Component
(把普通pojo实例化到spring容器中,相当于配置文件中的 <bean id="" class=""/>) 泛指各种组件,就是说当我们的类不属于各种归类的时候(不属于@Controller、@Services等的时候,孤儿注入),我们就可以使用@Component来标注这个类。(比如说工具类)
9、@Scope
@Scope注解的目的是用来调节作用域
@Scope("prototype")//多实例,IOC容器启动创建的时候,并不会创建对象放在容器在容器当中,当你需要的时候,需要从容器当中取该对象的时候,就会创建。 @Scope("singleton")//单实例(默认) IOC容器启动的时候就会调用方法创建对象,以后每次获取都是从容器当中拿同一个对象(map当中)。 @Scope("request")//同一个请求创建一个实例 @Scope("session")//同一个session创建一个实例