开发中常用到的注释

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装配顺序

  1. 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常

  2. 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常

    1. 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常

      1. 如果既没有指定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创建一个实例

10、@Transactional

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值