学习Spring Boot 注解,这一篇就够了(附带部分注解实例讲解)

发布时间 2024-01-08 22:08:14作者: DoubleLi

 


你接触的注解有哪些?常用的有哪些?能记住的有哪些?知道他们具体是干什么的吗?本章为你解惑。

 

本文采取分类的方式进行注解讲解,方便记忆,对于比较容易混淆的注解,给与了实例讲解,希望对你会有帮助。

一、web mvc开发时,对于三层的类注解

1.1 @Controller

应用在MVC层(控制层),DispatcherServlet会自动扫描注解了此注解的类,然后将web请求映射到注解了@RequestMapping的方法上。

1.2 @Service

应用在service层(业务逻辑层)

1.3 @Reponsitory

应用在dao层(实现类)(数据访问层)

1.4 @component

表示一个带注释的类是一个“组件”,成为Spring管理的Bean。当使用基于注解的配置和类路径扫描时,这些类被视为自动检测的候选对象。同时@Component还是一个元注解。

注意: @Controller、@Service、@Reponsitory都组合了 @Component注解。为了区分三层不同的作用,因此分别为三层起了不同的名字。

二、依赖注入的注解

依赖注入有那种方式,@Resource是jdk中的,@Autowired是spring的,两个都可以注入一个java bean。

2.1@Autowired

由Spring的依赖注入工具(BeanPostProcessor、BeanFactoryPostProcessor)自动注入,Spring提供的工具。这个注解是最常用的注解,请切记!

2.2 @Resource

依赖注入,给对象的属性注入数据,可以定义在字段上,也可以定义在方法上。一般用在注入dao层数据源,跟@Autowired相似,区别就是@Autowired默认是先根据类型,而@Resource默认是先根据名称

2.3 @Resource、@Autowired的区别

根据类型或者名称进行依赖注入,这又是什么意思呢 ? 有些小伙伴可能还不知道,下面介绍一下:

@Resource的作用相当于@Autowired,只不过@AutowiredbyType自动注入,而@Resource默认按 byName自动注入罢了。@Resource有两个属性是比较重要的,分是nametypeSpring@Resource注解的name属性解析为bean的名字,而type属性则解析为code>bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。
  @Resource装配顺序
  1. 如果同时指定了nametype,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
  2. 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
  3. 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
  4. 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;

这么长篇大论,可能你还是晕,下面我们用一个范例来讲解给你听:

2.3.1 实例讲解(错误实例)

新建Animal接口类
package com.ieslab.powergrid.demosvr.entity;

import org.springframework.stereotype.Component;

/**
 * 动物接口类
 */
@Component
public interface Animal {
    public void walk();
}
新建两个实现类Cat.java 和 Dog.java

这两个实现类都实现了walk()方法,但是执行内容不同,我们用打印日志不同区分一下。

package com.ieslab.powergrid.demosvr.entity;

import org.springframework.stereotype.Component;

@Component
public class Cat implements Animal{
    @Override
    public void walk() {
        System.out.println("cat walk");
    }
}

 

package com.ieslab.powergrid.demosvr.entity;

import org.springframework.stereotype.Component;

@Component
public class Dog implements Animal{
    @Override
    public void walk() {
        System.out.println("dog walk");
    }
}
编写测试用例
package com.ieslab.powergrid.demosvr.entity;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;


@SpringBootTest
class AnimalTest {
    @Autowired
    Animal animal;

    @Test
    void test(){
        animal.walk();
    }
}

 

这个测试用例,我们使用@AutowiredAnimal animal;进行依赖注入,我么知道@Autowired是根据类型进行注入的,这时候的类型就是Animal ,但是依赖注入是,是根据具体实现进行注入的,而且具体实现只能有一个时,他才能知道注入哪一个实现类,因此,此处这样写一定会报错,我们执行一下看看吧。

报错的地方给我们提示了:but found 2: Cat,Dog,思是Animal有两个实现类。解决方案如下:

  1. 还是使用@Autowired 注解,但是我们需要为其设置具体的实现类型,这是就需要一个新的注解:@Qualifier,如下图修改代码:
  2. 使用@Resource 注解,但是我们需要为其设置具体的实现的名称,如下代码:
package com.ieslab.powergrid.demosvr.entity;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;

@SpringBootTest
class AnimalTest2 {
    @Resource(name="cat") //注意是cat不是cat,因为使用@Service,容器为我们创建bean时默认类名首字母小写
    Animal animal;
    @Test
    void test(){
        animal.walk();
    }
}

2.4 @Value

由于@Autowired、@Qualifier、@Resource三者自动装配只能针对于注入其他bean类型的数据,而基本类型和String类型无法使用上述注解实现。因此有了@Value这个注解,@Value专门用来服务基本类型和String类型。

另外@Value注解有一个value 属性:用于指定数据的值。它可以使用spring中SpEL(也就是spring的EL表达式)。SpEL的写法:${表达式},当然也可以类似mybatis中的 #{表达式} 的写法

@Value("#{2*3}")  //#写法 表示6
private int age;

@Value("178")    //普遍写法 178
private int height;

@Value("${man.weight}")  //SpEL的写法一般操作配置文件中数据
private int weight;

总结:通过@Value注解将常量、配置文件中的值、其他bean的属性值注入到变量中,作为变量的初始值。支持表达式、直接赋值、配置文件三种方式。

2.5 @Data

有时候你会遇到@Data注解,其实这个注解和lombok插件有关,@Data 注解的主要作用是提高代码的简洁,使用这个注解可以省去代码中大量的get()、 set()、 toString()等方法;

三、WEB 常用的注解

3.1 @RequestMapping

用来映射web请求(访问路径和参数),处理类和方法的。可以注解在类和方法上,注解在方法上的@RequestMapping路径会继承注解在类上的路径。同时支持Serlvetrequestresponse作为参数,也支持对requestresponse的媒体类型进行配置。其中有value(路径),produces(定义返回的媒体类型和字符集),method(指定请求方式)等属性。

注意
@GetMapping和@PostMapping@RequestMapping的两种特例,一个是get方式请求,一个是post方式,此处不再描述。

3.2 @RequestParam

@RequestParam:将请求参数绑定到你控制器的方法参数上(是springmvc中接收普通参数的注解)
3.2.1 语法
语法1:
@RequestParam(value=”参数名”,required=”true/false”,defaultValue=””)
value:参数名

required:是否包含该参数,默认为true,表示该请求路径中必须包含该参数,如果不包含就报错。

defaultValue:默认参数值,如果设置了该值,required=true将失效,自动为false,如果没有传该参数,
就使用默认值

语法2:
@RequestParam("参数名")

 

3.2.2 实例
package com.ieslab.powergrid.demosvr.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/api")
public class TestController {
        /**
         * 接收普通请求参数
         * http://localhost:8080/api/test1?name=liu
         * url参数中的name必须要和@RequestParam("name")一致,
         * 因为请求参数绑定到你控制器的方法参数,所以方法参数可以自定义
         */
        @RequestMapping("/test1")
        @ResponseBody
        public String test1(@RequestParam("name")String name1){
            System.out.println(name1);
            return name1;
        }

        /**
         * 接收普通请求参数
         * http://localhost:8080/api/test2?name=lin
         * url参数中的name必须要和@RequestParam("name")一致
         * url中没有name参数不会报错、有就显示出来
         */
        @RequestMapping("/test2")
        @ResponseBody
        public String test2(@RequestParam(value="name",required=false)String name2){
            System.out.println(name2);
            return name2;
        }

        /**
         * 接收普通请求参数
         * http://localhost:8080/api/test3?name=zhang 显示为zhang
         * http://localhost:8080/api/test3?name 显示为hello,此时设置了默认值
         */
        @RequestMapping("/test3")
        @ResponseBody
        public String test3(@RequestParam(value="name",required=true,defaultValue="hello")String name3){
            System.out.println(name3);
            return name3;
        }
    }

注意: url中请求的参数名称一定要和@RequestParam(value="")中value的值保持一致。
实例中的三个案例的注释讲的很清楚,请仔细看看。

3.3 @PathVariable

@PathVariable 放置在参数前,用来接受路径参数。

@RequestMapping(value = "user/{username}")
public String test(@PathVariable(value="username") String username) {
	return "user"+username;
}

这里的{username}就是我们定义的变量规则,username是变量的名字, 注解@PathVariable(value=“username”) String username 会获取变量的值为方法中的参数赋值。

3.4 @RequestParam和@PathVariable区别

前者是在url中以参数方式传输,后者在请求url路径中根据变量传输,二者的应用场景建议如下:

1、当URL指向的是某一具体业务资源(或资源列表),例如个人博客或者用户时,使用@PathVariable
2、当URL需要对资源或者资源列表进行过滤,筛选时,用@RequestParam

例如我们会这样设计URL:

/blogs/{blogId}
/blogs?state=publish
而不是/blogs/state/publish来表示处于发布状态的博客文章

3.5 @ResponseBody和@RequestBody

@ResponseBody:将返回值放在response体内。返回的是数据而不是页面。在异步请求返回json数据时使用。
@RequestBody:允许request的参数在request体中,而不是在直接链接在地址的后面。此注解放置在参数前。比如:直接以String接收前端传过来的json数据:

/***
 * 直接以String接收前端传过来的json数据
 * 
 * @Param str:json格式的字符串
 * @return: json格式的字符串
 **/
@PostMapping("/test")
@ResponseBody
public String test(@RequestBody String str){
	return str;
}
 

3.6 @RestController

1)组合注解,组合了@Controller@ResponseBody,当我们只开发一个和页面交互数据的控制层的时候可以使用此注解。
2)使用此注解后,在方法层就不用添加@ResponseBody注解了,并且这个类中所有的方法都默认添加了@ResponseBody注解,都返回的是数据而不是界面。

3.7 @ControllerAdvice和@ExceptionHandler

@ControllerAdvice用在类上,声明一个控制器建言,它也组合了@Component注解,会自动注册为Spring的Bean。
ExceptionHandler用在方法上定义全局处理,通过他的value属性可以过滤拦截的条件:@ExceptionHandler(value=Exception.class)–表示拦截所有的Exception。
应用场景:统一异常处理:下面大概介绍一下,详细了解请查看本人写的文章:Springboot:统一异常处理:https://blog.csdn.net/houpeibin2012/article/details/104440752

四、Spring Boot常用的注解

4.1 @SpringBootApplication:启动

SpringBoot的核心注解,主要目的是开启自动配置。它也是一个组合注解,主要组合了@Configuration,@EnableAutoConfiguration(核心)和@ComponentScan。可以通过@SpringBootApplication(exclude={想要关闭的自动配置的类名.class})来关闭特定的自动配置,其中@ComponentScanspring Boot扫描到Configuration类并把它加入到程序上下文。

4.2 @EnableAutoConfiguration:自动配置

此注释自动载入应用程序所需的所有Bean——这依赖于Spring Boot在类路径中的查找。该注解组合了@Import注解,@Import注解导入了EnableAutoCofigurationImportSelector类,它使用SpringFactoriesLoader.loaderFactoryNames方法来扫描具有META-INF/spring.factories文件的jar包。而spring.factories里声明了有哪些自动配置.

4.3 @Configuration:配置文件

等同于springXML配置文件;使用Java代码可以检查类型安全。

4.4 @ComponentScan:自动扫描

表示将该类自动发现扫描组件。个人理解相当于,如果扫描到有@Component、@Controller、@Service等这些注解的类,并注册为Bean,可以自动收集所有的Spring组件,包括@Configuration类。

五、AOP常用的注解

5.1 @Aspect:切面

声明一个切面

5.2 @After:后置建言

后置建言(advice),在原方法前执行

5.3 @Before:前置建言

前置建言(advice),在原方法后执行。

5.3 @Around:环绕

环绕建言(advice),在原方法执行前执行,在原方法执行后再执行(@Around可以实现其他两种advice)。

5.3 @PointCut:切点

声明切点,即定义拦截规则,确定有哪些方法会被切入

六、测试常用的注解

6.1 @SpringBootTest

@SpringBootTest注解是SpringBoot Since:1.4.0 版本开始引入的一个用于测试的注解。

6.2 @Test

将一个普通方法修饰为一个测试方法。

6.3 @RunWith

这个是Junit的注解,springboot集成了junit。一般在测试类里使用:@RunWith(SpringJUnit4ClassRunner.class)
— SpringJUnit4ClassRunner在JUnit环境下提供Sprng TestContext Framework的功能
最主要是声明测试的运行器,都在org.junit.runners下。
@RunWith(SpringRunner.class) ,表明这个类中的测试用例需要使用SpringRunner类来执行。

6.4 其他测试注解

1. @Ignore : 被忽略的测试方法

2. @Before: 每一个测试方法之前运行

3. @After : 每一个测试方法之后运行

4. @BeforeClass: 所有测试开始之前运行

5. @AfterClass: 所有测试结束之后运行

 

七、其他注解:都是比较常用的

7.1 @Transactional:事务声明

声明事务(一般默认配置即可满足要求,当然也可以自定义)

7.2 @Cacheable:缓存

声明数据缓存

7.3 @PropertySource:文件引入

指定文件地址。提供了一种方便的、声明性的机制,用于向Spring的环境添加PropertySource。与@configuration类一起使用。

7.4 @Async:多线程异步方法

注解在方法上标示这是一个异步方法,在类上标示这个类所有的方法都是异步方法。

7.5 @EnableAsync:多线程

开启异步任务支持。注解在配置类上。

7.6 @EnableScheduling:开启计划任务

注解在配置类上,开启对计划任务的支持。

7.7 @Scheduled:计划任务

注解在方法上,声明该方法是计划任务。支持多种类型的计划任务:cron,fixDelay,fixRate。