spring项目常见注解的功能
1.spring和springmvc常见注解
1.1 controller注解
@Controller用于标记在一个类上,使用它标记的类就是一个SpringMVC的 Controller类,分发处理器会扫描使用该注解的类的方法,并检测该方法是否使用了@RequestMapping 注解。
1.2 @RequestMapping注解
在Spring MVC 中使用 @RequestMapping 来映射请求,也就是通过它来指定控制器可以处理哪些URL请求,相当于Servlet中在web.xml中配置。
<servlet>
<servlet-name>servletName</servlet-name>
<servlet-class>ServletClass</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servletName</servlet-name>
<url-pattern>url</url-pattern>
</servlet-mapping>
使用举例
将 @RequestMapping 注解在 login 方法上,而UserController上不添加 @RequestMapping 注解,这时的请求 URL 是相对于 Web 根目录
@Controller
public class UserController {
@RequestMapping("/login")
public String login() {
return "success";
}
}
@RequestMapping 的 method 属性
@RequestMapping 中的 method 主要用来定义接收浏览器发来的何种请求。在Spring中,使用枚举类
@RequestMapping(value=“/login”,method=RequestMethod.GET) 来指定 login()方法 仅处理通过 GET 方式发来的请求
@Controller
@RequestMapping(path = "/user")
public class UserController {
@RequestMapping(path = "/login", method=RequestMethod.GET)
public String login() {
return "success";
}
}
@RequestMapping(value=“/login”,method=RequestMethod.POST) 来指定 login()方法 仅处理通过 POST 方式发来的请求
@Controller
@RequestMapping(path = "/user")
public class UserController {
@RequestMapping(path = "/login", method=RequestMethod.POST)
public String login() {
return "success";
}
}
由于在 RequestMapping 注解类中 method() 方法返回的是 RequestMethod 数组,所以可以给 method 同时指定多个请求方式
@Controller
@RequestMapping(path = "/user")
public class UserController {
@RequestMapping(path = "/login", method={RequestMethod.POST,RequestMethod.GET})
public String login() {
return "success";
}
}
@RequestMapping 的 params 属性
该属性表示请求参数,也就是追加在URL上的键值对,多个请求参数以&隔开,例如:
http://localhost/SpringMVC/user/login?username=kolbe&password=123456
@Controller
@RequestMapping(path = "/user")
public class UserController {
@RequestMapping(path = "/login", params={"username=kolbe","password=123456"})
public String login() {
return "success";
}
}
@RequestMapping 的 headers 属性
该属性表示请求头
用于HTTP协义交互的信息被称为HTTP报文,客户端发送的HTTP报文被称为请求报文,服务器发回给客户端的HTTP报文称为响应报文,报文由报文头部和报文体组成。
请求头部(Request Headers):请求头包含许多有关客户端环境和请求正文的信息,例如浏览器支持的语言、请求的服务器地址、客户端的操作系统等。
响应头部(Rsponse Headers):响应头也包含许多有用的信息,包括服务器类型、日期、响应内容的类型及编码,响应内容的长度等等。
通过 @RequestMapping 中的 headers 属性,可以限制客户端发来的请求
@Controller
@RequestMapping(path = "/user")
public class UserController {
@RequestMapping(path = "/login", headers="Host=localhost:8080")
public String login() {
return "success";
}
}
带占位符的URL
可以通过 @PathVariable 将 URL 中的占位符绑定到控制器的处理方法的参数中,占位符使用{}括起来
@Controller
@RequestMapping(path = "/user")
public class UserController {
@RequestMapping(value="/{id}", method=RequestMethod.GET)
public String show(@PathVariable("id") Integer id) {
return "success";
}
}
在这个控制器中 show() 方法将可以接收 user/1、user/2、user/3等等的路径请求,请求的方法必须为GET,使用 @PathVariable 为应用实现 REST 规范提供了具大的便利条件。
采用REST风格的URL请求
REST(Representational State Transfer):(资源)表现层状态转化,它是目前最流行的一种软件架构,其结构清晰、易于理解、扩展方便且符合标准,正在越来越多的被实践到应用中。
REST 风格的 URL 请求
请求路径 请求方法 作用
-/user/1 HTTP GET 得到id为1的user
-/user/1 HTTP DELETE 删除id为1的user
-/user/1 HTTP PUT 更新id为1的user
-/user HTTP POST 新增user
由于浏览器表单只支持 GET 和 POST 请求,为了实现 DELETE 和 PUT 请求,Spring 为我们提供了一个过滤器org.springframework.web.filter.HiddenHttpMethodFilter,可以为我们将 GET 和 POST 请求通过过滤器转化成 DELETE 和 PUT 请求。
修改后的UserController代码
package cn.kolbe.spring.mvc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
@RequestMapping(path = "/user")
public class UserController {
@RequestMapping(value="/{id}", method=RequestMethod.GET)
public String show(@PathVariable("id") Integer id) {
System.out.println("查看id为:" + id + "的user");
return "success";
}
@RequestMapping(value="/{id}", method=RequestMethod.PUT)
public String update(@PathVariable("id") Integer id) {
System.out.println("更新id为:" + id + "的user");
return "success";
}
@RequestMapping(value="/{id}", method=RequestMethod.DELETE)
public String destroy(@PathVariable("id") Integer id) {
System.out.println("删除id为:" + id + "的user");
return "success";
}
@RequestMapping(value="", method=RequestMethod.POST)
public String create() {
System.out.println("新建user");
return "success";
}
}
1.3 @ResponseBody注解
@ResponseBody的作用其实是将java对象转为json格式的数据。
@responseBody注解的作用是将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML数据。
@ResponseBody是作用在方法上的,@ResponseBody 表示该方法的返回结果直接写入 HTTP response body 中,一般在异步获取数据时使用【也就是AJAX】。
后台 Controller类中对应的方法:
@RequestMapping("/login.do")
@ResponseBody
public Object login(String name, String password, HttpSession session) {
user = userService.checkLogin(name, password);
session.setAttribute("user", user);
return new JsonResult(user);
}
@RequestBody是作用在形参列表上,用于将前台发送过来固定格式的数据【xml格式 或者 json等】封装为对应的 JavaBean 对象,
封装时使用到的一个对象是系统默认配置的 HttpMessageConverter进行解析,然后封装到形参上。
如上面的登录后台代码可以改为:
@RequestMapping("/login.do")
@ResponseBody
public Object login(@RequestBody User loginUuser, HttpSession session) {
user = userService.checkLogin(loginUser);
session.setAttribute("user", user);
return new JsonResult(user);
}
1.4 @RequestBody注解
@RequestBody 注解则是将 HTTP 请求正文插入方法中,使用适合的 HttpMessageConverter 将请求体写入某个对象。
- 该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上;
- 再把HttpMessageConverter返回的对象数据绑定到controller中方法的参数上。
使用时机
GET、POST方式提时, 根据request header Content-Type的值来判断:
application/x-www-form-urlencoded, 可选(即非必须,因为这种情况的数据@RequestParam, @ModelAttribute
也可以处理,当然@RequestBody也能处理);
multipart/form-data, 不能处理(即使用@RequestBody不能处理这种格式的数据);
其他格式, 必须(其他格式包括application/json, application/xml等。这些格式的数据,必须使用@RequestBody来处理);
PUT方式提交时, 根据request header Content-Type的值来判断:
application/x-www-form-urlencoded, 必须;multipart/form-data, 不能处理;其他格式, 必须;
说明:request的body部分的数据编码格式由header部分的Content-Type指定;
@RequestMapping(value = "user/login")
@ResponseBody
public User login(@RequestBody User user) {
return user;
}
1.5 @RestController注解
@RestController注解相当于@ResponseBody + @Controller合在一起的作用
@Controller 将当前修饰的类注入SpringBoot IOC容器,使得从该类所在的项目跑起来的过程中,这个类就被实例化。 @ResponseBody 它的作用简短截说就是指该类中所有的API接口返回的数据,甭管你对应的方法返回Map或是其他Object,它会以Json字符串的形式返回给客户端
@SpringBootApplication
@RestController
public class App
{
public static void main( String[] args )
{
SpringApplication.run(App.class);
}
@RequestMapping("hello")
public String sayHello(){
return "hello 1805,springboot";
}
}
1.6 @Autowired注解
基本概念
首先了解一下IOC操作Bean管理,bean管理是指(1)spring创建对象 (2)spring注入属性。当我们在将一个类上标注@Service或者@Controller或@Component或@Repository注解之后,spring的组件扫描就会自动发现它,并且会将其初始化为spring应用上下文中的bean。 当需要使用这个bean的时候,例如加上@Autowired注解的时候,这个bean就会被创建。而且初始化是根据无参构造函数。
举例
@Data
@Service
public class AutoWiredBean {
private int id;
private String name;
public AutoWiredBean(){
System.out.println("无参构造函数");
}
public AutoWiredBean(int id, String name) {
this.id = id;
this.name = name;
System.out.println("有参构造函数");
}
}
在springboot项目的测试类中进行测试,代码如下
@SpringBootTest
@RunWith(SpringRunner.class)
class Springboot02WebApplicationTests {
private AutoWiredBean autoWiredBean;
@Autowired
public Springboot02WebApplicationTests (AutoWiredBean autoWiredBean){
this.autoWiredBean = autoWiredBean;
}
@Test
void contextLoads() {
System.out.println(autoWiredBean);
System.out.println(autoWiredBean.getId());
System.out.println(autoWiredBean.getName());
}
}
控制台输出的结果如下: 将下面代码注释了在运行
输出结果如下: 从这我们可以看到无论有没有使用AutoWiredBean 类,它都被spring通过无参构造函数初始化了。当将被使用时才会创建。
作用
@Autowired可以标注在属性上、方法上和构造器上,来完成自动装配。默认是根据属性类型,spring自动将匹配到的属性值进行注入,然后就可以使用这个属性。
它可以标注在属性上、方法上和构造器上,那有什么区别吗?简单来说因为类成员的初始化顺序不同,静态成员 ——> 变量初始化为默认值——>构造器——>为变量赋值。如果标注在属性上,则在构造器中就不能使用这个属性(对象)的属性和方法。
对构造函数标注注解,如图在构造器上标注@Autowired注解
当标注的属性是接口时,其实注入的是这个接口的实现类, 如果这个接口有多个实现类,只使用@Autowired就会报错,因为它默认是根据类型找,然后就会找到多个实现类bean,所有就不知道要注入哪个。然后它就会根据属性名去找。所以如果有多个实现类可以配合@Qualifier(value=“类名”)来使用 (是根据名称来进行注入的)
1.7 @Component注解
@component (把普通pojo实例化到spring容器中,相当于配置文件中的 ) 泛指各种组件,就是说当我们的类不属于各种归类的时候(不属于@Controller、@Services等的时候),我们就可以使用@Component来标注这个类。
@Compent 作用就相当于 XML配置
@Component
public class Student {
private String name = "lkm";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
1.8 @Bean注解
@Bean 需要在配置类中使用,即类上需要加@Configuration注解
@Configuration
public class WebSocketConfig {
@Bean
public Student student(){
return new Student();
}
}
那为什么有了@Compent,还需要@Bean呢? 如果你想要将第三方库中的组件装配到你的应用中,在这种情况下,是没有办法在它的类上添加@Component注解的,因此就不能使用自动化装配的方案了,但是我们可以使用@Bean,当然也可以使用XML配置。
1.9 @Configuration注解
@Configuration的作用类似于配置一个spring-bean.xml中的标签的作用,主要用于Bean的注入,放置在类上。使用该注解注入Bean后,获取IOC容器的方式不再使用ClassPathXmlApplicationContext或者文件系统路径来获取对应的IOC容器,而是使用 AnnotationConfigApplicationContext(AnnotationConfiguration.class)的方式来获取IOC容器(AnnotationConfiguration为自定义的配置类)。
举例
在自定义的配置类中,注入普通的Bean
public class Book {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Book()
{
System.out.println("Book无参构造器");
}
public Book(String name) {
super();
this.name = name;
System.out.println("有参构造器");
}
@Override
public String toString() {
return "Book--> [name=" + name + "]";
}
}
@Configuration
public class AnnotationConfiguration {
public AnnotationConfiguration() {
System.out.println("初始化");
}
@Bean
public Book book()
{
Book book=new Book();
book.setName("C++");
return book;
}
}
AnnotationConfigApplicationContext acac=
new AnnotationConfigApplicationContext(AnnotationConfiguration.class);
Book book=(Book) acac.getBean("book");
System.out.println(book);
执行结果: 注入复杂的Bean(一个Bean的属性,为该配置类中的另一个Bean)
@Configuration
@Import(AnotherConfiguration.class)
public class AnnotationConfiguration {
public AnnotationConfiguration() {
System.out.println("初始化");
}
@Bean
public Book book()
{
Book book=new Book();
book.setName("C++");
return book;
}
@Bean
public Student student(Book book)
{
Student student=new Student();
student.setBook(book);
return student;
}
}
1.10 @Value注解
作用
该注解的作用是将我们配置文件的属性读出来,有@Value(“${}”)和@Value(“#{}”)两种方式
举例
我使用的是springboot搭建的项目,配置文件application.propertites已经被加载到了项目中,application.propertites配置属性如下:
我们读取他的 server.port 属性,springMVC的controller结构如下: 运行程序 看到:
1.11 @PostConstruct注解
@PostContruct是Java自带的注解,在方法上加该注解会在项目启动的时候执行该方法,也可以理解为在spring容器初始化的时候执行该方法。
执行顺序
Constructor >> @Autowired >> @PostConstruct
1.12 @Resource注解
java的注解,属性较多,type无法分辨时可以用name分辨
与@Autowired对比
spring的注解,一个属性,type无法分辨时需要借助@Qualifier注解才能使用 使用@Autowired方式最好使用构造函数的方式注入。
Collection<String> union = CollectionUtils.union(a, b);
Collection<String> intersection = CollectionUtils.intersection(a, b);
Collection<String> disjunction = CollectionUtils.disjunction(a, b);
Collection<String> subtract = CollectionUtils.subtract(a, b);
Boolean boolean = CollectionUtils.isEmpty(Collection<?> collection);
Boolean boolean = CollectionUtils.isNotEmpty(Collection<?> collection);
1.13 @GetMapping注解和@PostMapping注解
@GetMapping用于处理请求方法的GET类型,@ PostMapping用于处理请求方法的POST类型等
@GetMapping(value = "/test")
1.14 @RequestParam注解
@RequestParam是来传递参数的,用于将请求参数区数据映射到功能处理方法的参数上。
public String XXX(@RequestParam(value = "Id", required = false) String Id,)
@RequestParam主要参数
value:参数名字,即入参的请求参数名字,如username表示请求的参数区中的名字为username的参数的值将传入; required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报404错误码; defaultValue:默认值,表示如果请求中没有同名参数时的默认值,默认值可以是SpEL表达式,如: #{systemProperties[‘java.vm.version’]}
使用
public String requestparam5(
@RequestParam(value="username", required=true, defaultValue="zhang") String username)
1.15 @Service注解
@Service注解用于类上,标记当前类是一个service类,加上该注解会将当前类自动注入到spring容器中,不需要再在applicationContext.xml文件定义bean了。
1.16
2.日志相关的注解
2.1@Slf4j注解
在使用springboot时,添加lombok依赖包
<!-- 该依赖是针对日志的相关包-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
具体使用
首先具体的使用分为多种情况,但是我们在开发中主要涉及到的就是两种:
1)可以打印string字符串。 2)或者是string字符串拼接对象。
@Slf4j
@RestController
public class GuoBiaoSynController {
@PostMapping("/gcg")
public void getInfo(@RequestBody JSONObject jsonObject) {
String temp = JSON.toJSONString(jsonObject);
log.info("国标云请求体:{}", jsonObject);
log.info(JSON.toJSONString(jsonObject));
log.info("00000000000000000");
log.info(jsonObject.getString("Header"));
}
}
其实在开发中比较常用的就是打印Object对象,但是打印Object对象就要采用string拼接的方式,这种方式要有{}符号,因为达表示将要输出的东西进行了包装放进{}中。
3. lombok相关注解
3.1 @Data注解
@Data注解是由Lombok库提供的,会生成getter、setter以及equals()、hashCode()、toString()等方法
3.2 @Builder.Default注解
设置实体类默认值
@Builder.Default
long lastPong = System.currentTimeMillis();
private int sendTimeLimit = 10 * 1000;
private int sendBufferSizeLimit = 512 * 1024;
long establishTime;
long payloadCount;
3.3 @AllArgsConstructor注解
@AllArgsConstructor 注解作用在类上,使用后为类生成一个全参构造函数(含有已申明的所有属性参数)
3.4 @NoArgsConstructor注解
@NoArgsConstructor 注解作用在类上,使用后为类生成一个无参构造函数
3.5 @Builder注解
@Builder注解的作用主要是用来生成对象,并且可以为对象链式赋值。
使用
给我们的实体类加上一个@Builder注解 使用@Builder注解生成对象
3.6 @ToString注解
作用于类,覆盖默认的 toString() 方法
使用场景:使用在被 @ApiModel 注解的模型类的属性上。表示对model属性的说明或者数据操作更改 。 概述:添加和操作模型属性的数据。
4. Java原生注解
4.1 @NotNull注解
这里平时写实体类后Controller层接收了都是用if(XXX!=null){}来判断是否为空这样显然代码冗余性
这里如果在实体类的这个属性上面@NotNull既可以完成这个判断
5.springcloud注解
5.1 @FeignClient注解
常用属性
举例
@FeignClient(value = "abc", url = "${custom.abcUrl:}", fallbackFactory =
NoExistTestClient.NoExistTestClientFallback.class, configuration = FeignDefaultConfiguration.class)
public interface NoExistTestClient {
@RequestMapping(method = RequestMethod.POST, value = "/abc", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
WsResp textSemantic(@RequestBody HighFreedomDialogReq req);
@Slf4j
@Component
class NoExistTestClientFallback implements FallbackFactory<NoExistTestClient> {
@Override
public NoExistTestClient create(Throwable throwable) {
return req -> WsResp.fail(Constants.SERVER_ERROR, "ABC服务降级," + throwable.getMessage(), req.getMsgId());
}
}
}
|