Spring Boot是一种用于构建独立的、基于Java的生产级应用程序的框架,它简化了Java开发过程并提供了许多有用的功能和注解。在使用Spring Boot开发Web应用程序时,我们通常会使用到一些常见的注解来配置和管理应用程序的各个方面。下面是一些常见的Spring Boot Web开发使用到的注解:
-
@SpringBootApplication:这是一个组合注解,它包含了@Configuration、@EnableAutoConfiguration和@ComponentScan三个注解。@Configuration用于配置应用程序上下文,@EnableAutoConfiguration用于启用自动配置机制,@ComponentScan用于扫描指定包下的组件。
在这个示例中,我们创建了一个名为DemoApplication的主类,并在该类上添加@SpringBootApplication注解。这样,Spring Boot会自动扫描该类所在的包及其子包下所有的组件,并将它们装配到Spring容器中。
在main方法中,我们使用SpringApplication.run()方法启动了Spring Boot应用程序。该方法接受两个参数:第一个参数是主类的Class对象,第二个参数是命令行参数。
通过以上配置,Spring Boot会根据类路径、注解等信息进行自动配置,并启动一个嵌入式的Tomcat服务器,监听默认的HTTP端口(通常是8080)。然后,我们可以编写控制器、服务等组件来实现具体的业务逻辑,Spring Boot会自动将这些组件装配到Spring容器中并处理相应的请求。
该示例是一个最基本的示例,实际开发中可能会涉及更多的配置和组件。但@SpringBootApplication注解的作用就是简化了这些配置,让我们能够更快速地搭建和启动一个Spring Boot应用程序。
-
@Controller:这个注解用于将一个类声明为控制器(Controller),处理客户端请求并返回响应。
我们创建了一个名为MyController的控制器,并在该类上添加@Controller注解。这样,Spring Boot会自动扫描该类并将其装配到Spring容器中。
接着,我们定义了一个方法home(),该方法使用@GetMapping注解将HTTP GET请求映射到根路径"/"上。该方法接受一个ModelMap对象作为参数,用于存储和传递数据。
在方法体中,我们向ModelMap对象中添加了一个名为"message"的属性,值为"Hello, Spring Boot!"。然后,我们返回了一个名为"home"的视图名,告诉Spring Boot要渲染哪个视图模板。
返回的视图名"home"并不是一个具体的视图文件名,而是根据配置文件中的视图解析器来进行解析。通常情况下,Spring Boot会默认使用Thymeleaf作为视图解析器,它会自动查找名为"home.html"或"home.thymeleaf"等文件,并将ModelMap对象中的数据渲染到该文件中。
通过以上配置,我们可以在浏览器中访问根路径"/",并看到输出"Hello, Spring Boot!"的页面。这个页面是由Thymeleaf视图模板生成的,其中包含了我们在控制器中添加的数据。
-
@RestController:这个注解是@Controller和@ResponseBody的组合注解,用于声明一个控制器,并将控制器的每个方法的返回值直接序列化为JSON或XML响应。
我们创建了一个名为MyRestController的REST控制器,并在该类上添加@RestController注解。这样,Spring Boot会自动扫描该类并将其装配到Spring容器中。接着,我们定义了一个方法hello(),该方法使用@GetMapping注解将HTTP GET请求映射到路径"/hello"上。该方法返回一个字符串"Hello, Spring Boot!"作为响应体。
由于@RestController注解的存在,Spring Boot会自动将方法返回的字符串包装成一个JSON格式的响应体,并设置Content-Type为application/json。
我们可以在浏览器或其他HTTP客户端中发送GET请求到路径"/hello",并收到一个JSON格式的响应体:"Hello, Spring Boot!"。这个响应体是由Spring Boot自动封装和生成的。
-
@RequestMapping:这个注解用于将HTTP请求映射到控制器方法上。可以用于指定请求的URL路径、请求方法、请求参数等。
我们创建了一个名为MyController的REST控制器,并在该类上添加@RestController注解。同时,我们在类级别上添加了@RequestMapping注解,并指定了根路径"/api"。接着,我们定义了一个方法hello(),该方法使用@RequestMapping注解将HTTP GET请求映射到路径"/hello"上。我们还使用@RequestMapping注解指定了请求的请求方法为GET。
我们可以通过value属性来指定具体的请求路径,如"/hello"。同时,通过method属性来指定请求的请求方法,如RequestMethod.GET表示只接受GET请求。
通过以上配置,我们可以在浏览器或其他HTTP客户端中发送GET请求到路径"/api/hello",并收到一个值为"Hello, Spring Boot!"的响应。这个路径是由类级别的@RequestMapping注解加上方法级别的@RequestMapping注解共同确定的。
-
@GetMapping:这个注解是@RequestMapping(method = RequestMethod.GET)的缩写形式,用于将HTTP GET请求映射到控制器方法上。
我们创建了一个名为MyRestController的REST控制器,并在该类上添加@RestController注解。接着,我们定义了一个方法hello(),该方法使用@GetMapping注解将HTTP GET请求映射到路径"/hello"上。方法体中返回了一个字符串"Hello, Spring Boot!"作为响应体。
我们可以在浏览器或其他HTTP客户端中发送GET请求到路径"/hello",并收到一个字符串"Hello, Spring Boot!"作为响应。@GetMapping注解是@RequestMapping注解的缩写形式,用于简化只有GET请求的情况。
-
@PostMapping:这个注解是@RequestMapping(method = RequestMethod.POST)的缩写形式,用于将HTTP POST请求映射到控制器方法上。
我们创建了一个名为MyRestController的REST控制器,并在该类上添加@RestController注解。接着,我们定义了一个方法hello(),该方法使用@PostMapping注解将HTTP POST请求映射到路径"/hello"上。方法体中接受一个@RequestBody注解的String类型参数name,并返回一个字符串"Hello, " + name + "!"作为响应体。
@RequestBody注解表示将请求体中的内容绑定到方法参数上,从而获取POST请求中提交的数据。
我们可以在浏览器或其他HTTP客户端中发送POST请求到路径"/hello",并在请求体中提交任意字符串作为name参数的值。服务器会将其解析为方法hello()的参数name,并返回一个形如"Hello, name!"的响应体。
-
@PutMapping:这个注解是@RequestMapping(method = RequestMethod.PUT)的缩写形式,用于将HTTP PUT请求映射到控制器方法上。
我们创建了一个名为MyRestController的REST控制器,并在该类上添加@RestController注解。接着,我们定义了一个方法hello(),该方法使用@PutMapping注解将HTTP PUT请求映射到路径"/hello"上。方法体中接受一个@RequestBody注解的String类型参数name,并返回一个字符串"Hello, " + name + "! This is a PUT request."作为响应体。
@RequestBody注解表示将请求体中的内容绑定到方法参数上,从而获取PUT请求中提交的数据。
我们可以在浏览器或其他HTTP客户端中发送PUT请求到路径"/hello",并在请求体中提交任意字符串作为name参数的值。服务器会将其解析为方法hello()的参数name,并返回一个形如"Hello, name! This is a PUT request."的响应体。
-
@DeleteMapping:这个注解是@RequestMapping(method = RequestMethod.DELETE)的缩写形式,用于将HTTP DELETE请求映射到控制器方法上。
我们创建了一个名为MyRestController的REST控制器,并在该类上添加@RestController注解。接着,我们定义了一个方法deleteUser(),该方法使用@DeleteMapping注解将HTTP DELETE请求映射到路径"/users/{id}"上。方法体中通过@PathVariable注解将路径中的{id}部分绑定到方法参数userId上,作为要删除的用户ID。
@PathVariable注解用于将URL路径中的变量绑定到方法参数上。
我们可以在浏览器或其他HTTP客户端中发送DELETE请求到路径"/users/1"(其中1是要删除的用户ID),服务器会收到请求并执行相应的删除用户逻辑,然后返回一个形如"User with ID: 1 has been deleted."的响应体。
-
@PathVariable:这个注解用于将URL路径中的变量绑定到方法参数上。
我们创建了一个名为MyRestController的REST控制器,并在该类上添加@RestController注解。接着,我们定义了一个方法getUser(),该方法使用@GetMapping注解将HTTP GET请求映射到路径"/users/{id}"上。方法体中通过@PathVariable注解将路径中的{id}部分绑定到方法参数userId上,作为要获取的用户ID。
@PathVariable注解用于将URL路径中的变量绑定到方法参数上。
我们可以在浏览器或其他HTTP客户端中发送GET请求到路径"/users/1"(其中1是要获取的用户ID),服务器会收到请求并执行相应的获取用户逻辑,然后返回一个形如"User with ID: 1"的响应体。
-
@RequestParam:这个注解用于将请求参数绑定到方法参数上。
我们创建了一个名为MyRestController的REST控制器,并在该类上添加@RestController注解。接着,我们定义了一个方法hello(),该方法使用@GetMapping注解将HTTP GET请求映射到路径"/hello"上。方法体中通过@RequestParam注解将请求参数name绑定到方法参数name上。
@RequestParam注解用于将请求参数绑定到方法参数上。
通过以上配置,我们可以在浏览器或其他HTTP客户端中发送GET请求到路径"/hello?name=John",其中name参数的值为John。服务器会收到请求并将name参数的值绑定到方法参数name上,然后返回一个形如"Hello, John!"的响应体。
-
@RequestBody:这个注解用于将请求体中的内容绑定到方法参数上。
我们创建了一个名为MyRestController的REST控制器,并在该类上添加@RestController注解。接着,我们定义了一个方法createUser(),该方法使用@PostMapping注解将HTTP POST请求映射到路径"/users"上。方法体中通过@RequestBody注解将请求体中的JSON数据绑定到方法参数user上。
@RequestBody注解用于将请求体中的数据绑定到方法参数上。
在这个示例中,我们假设存在一个名为User的类,该类具有名为name的属性。Spring框架会自动根据请求体中的JSON数据结构,将其转换为User对象。
我们可以在浏览器或其他HTTP客户端中发送POST请求到路径"/users",请求体中包含一个JSON数据,例如:
服务器会收到请求并将请求体中的JSON数据转换为User对象,然后执行相应的创建用户逻辑,并返回一个形如"User created: John"的响应体。 -
@ResponseBody:这个注解用于将方法的返回值直接序列化为HTTP响应体。
我们创建了一个名为MyRestController的REST控制器,并在该类上添加@RestController注解。接着,我们定义了一个方法hello(),该方法使用@GetMapping注解将HTTP GET请求映射到路径"/hello"上。方法体中通过@ResponseBody注解将返回值"Hello, world!"转换为HTTP响应体,即一个字符串"Hello, world!"。
Spring框架会自动将Java对象转换为JSON格式或XML格式的HTTP响应体,前提条件是要求对象具有相应的映射关系。
我们可以在浏览器或其他HTTP客户端中发送GET请求到路径"/hello",服务器会收到请求并执行相应的方法逻辑,然后返回一个形如"Hello, world!"的响应体。
-
@ResponseStatus:这个注解用于设置方法的HTTP响应状态码。
我们创建了一个名为MyRestController的REST控制器,并在该类上添加@RestController注解。接着,我们定义了两个方法:hello()和error()。
方法hello()使用@GetMapping注解将HTTP GET请求映射到路径"/hello"上,并通过@ResponseStatus(HttpStatus.OK)注解指定了成功的HTTP响应状态码为200。
方法error()使用@GetMapping注解将HTTP GET请求映射到路径"/error"上,并通过@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)注解指定了发生错误时的HTTP响应状态码为500(服务器内部错误)。该方法会抛出一个RuntimeException来模拟错误情况。
@ResponseStatus注解可以应用在方法级别或类级别上。当应用在方法级别上时,该注解会覆盖类级别上的注解。
我们可以在浏览器或其他HTTP客户端中发送GET请求到路径"/hello",服务器会收到请求并返回一个形如"Hello, world!"的响应体,并且HTTP响应状态码为200。
如果发送GET请求到路径"/error",服务器会收到请求并抛出RuntimeException,触发错误情况。此时,服务器会返回一个HTTP响应状态码为500(服务器内部错误)的响应。
-
@ExceptionHandler:这个注解用于定义异常处理方法,当控制器方法抛出指定类型的异常时,会调用该方法进行处理。
我们创建了一个名为MyRestController的REST控制器,并在该类上添加@RestController注解。接着,我们定义了三个方法:hello()、error()和两个异常处理方法handleRuntimeException()和handleException()。
方法hello()使用@GetMapping注解将HTTP GET请求映射到路径"/hello"上,并返回一个字符串"Hello, world!"作为HTTP响应体。
方法error()使用@GetMapping注解将HTTP GET请求映射到路径"/error"上,并抛出一个RuntimeException来模拟错误情况。
方法handleRuntimeException()使用@ExceptionHandler(RuntimeException.class)注解来处理抛出的RuntimeException异常,并返回一个字符串"Error: "加上异常的消息作为HTTP响应体。注意,该方法的返回值会替换掉原本由error()方法抛出的RuntimeException异常。
方法handleException()使用@ExceptionHandler(Exception.class)注解来处理所有未处理的异常,并返回一个字符串"An error occurred: "加上异常的消息作为HTTP响应体。该方法还通过@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)注解指定了HTTP响应状态码为500(服务器内部错误)。
@ExceptionHandler注解可以应用在控制器类或控制器方法上,用于处理特定的异常类型。
我们可以在浏览器或其他HTTP客户端中发送GET请求到路径"/hello",服务器会收到请求并返回一个形如"Hello, world!"的响应体。
如果发送GET请求到路径"/error",服务器会收到请求并抛出RuntimeException异常,此时,控制器会自动调用handleRuntimeException()方法来处理异常,并返回一个形如"Error: Something went wrong"的响应体。
如果发送GET请求到路径"/unknown",服务器会收到请求但找不到相应的处理方法,此时,控制器会自动调用handleException()方法来处理异常,并返回一个形如"An error occurred: No handler found for GET /unknown"的响应体,并且HTTP响应状态码为500(服务器内部错误)。
-
@Validated:这个注解用于开启方法参数的验证功能,可以对请求参数进行校验。
我们创建了一个名为MyRestController的REST控制器,并在该类上添加@RestController和@Validated注解。接着,我们定义了一个方法createUser(),使用@PostMapping注解将HTTP POST请求映射到路径"/user"上,并接受一个UserDto对象作为请求体。
在方法参数上,我们使用了@Validated注解来启用参数验证,以确保传入的UserDto对象满足验证规则。
UserDto类是一个简单的数据传输对象,其中包含了一些字段和对应的验证注解:
在UserDto类中,我们使用了javax.validation.constraints包下的@NotBlank注解,它表示字符串字段不能为空。如果传入的字段为空,则会触发验证失败,并返回相应的错误消息。当我们发送一个POST请求到路径"/user",并且请求体中的UserDto对象不满足验证规则时,Spring MVC会自动返回一个HTTP响应状态码为400(请求无效)的响应,并包含验证失败的错误消息。
例如,如果我们发送以下请求:
由于用户名字段为空,不满足@NotBlank注解的要求,服务器会返回一个形如以下的响应:
这样我们就可以在控制器中使用@Validated注解和相关的验证注解来实现对请求参数的验证。 -
@Autowired:这个注解用于自动注入依赖,可以将其他组件或配置注入到当前类中。
我们创建了一个名为UserService的服务类,并在该类上添加@Service注解,表示它是一个被Spring管理的Bean。接着,我们定义了一个私有的UserRepository类型的字段userRepository,并使用@Autowired注解在构造函数上进行自动装配。
构造函数@Autowired注解告诉Spring容器在创建UserService实例时,自动将匹配的UserRepository实例注入到构造函数中。
UserRepository是一个数据访问类,它可能具有自己的依赖项和其他方法,这里我们只关注如何使用@Autowired注解进行自动装配。
当我们需要在其他类中使用UserService时,可以直接通过@Autowired注解进行自动装配,而不需要手动创建UserService实例。
例如,假设我们有一个名为UserController的控制器类,需要使用UserService来处理用户相关的请求:
在UserController中,我们使用@Autowired注解将UserService自动装配到私有的userService字段上。这样,在处理"/users"路径的GET请求时,我们可以直接通过userService调用相应的方法来处理用户相关的逻辑。
@Autowired注解可以应用于构造函数、字段、setter方法和任意的方法上。Spring会根据依赖项的类型进行自动装配。
我们可以在其他类中使用@Autowired注解来自动装配需要的依赖项,简化了对象创建和依赖关系管理的过程。
-
@Value:这个注解用于从配置文件中读取属性值,并将其注入到当前类的字段或方法参数中。
我们创建了一个名为MyComponent的组件类,并在该类上添加@Component注解,表示它是一个被Spring管理的Bean。接着,我们定义了一个私有的String类型的字段myProperty,并使用@Value注解将外部属性值
${my.property}
注入到该字段中。${my.property}
是一个占位符,表示需要从外部属性文件中获取名为my.property
的属性值。要使@Value注解正常工作,我们需要在Spring配置文件(例如application.properties或application.yml)中定义相应的属性:
在application.properties中:
或者在application.yml中:
Spring容器在创建MyComponent实例时,会自动将${my.property}
的值(即"Hello, World!")注入到myProperty字段中。现在,我们可以在MyComponent类中使用myProperty字段来访问注入的属性值。
例如,假设我们在MyComponent类中定义了一个方法:
当调用printProperty()方法时,它会打印出注入的属性值:"Hello, World!"。需要注意的是,@Value注解还可以用于构造函数、方法参数和集合类型字段上。它提供了一种方便的方式来注入外部属性值到Spring Bean中。
通过以上配置,我们可以使用@Value注解来注入外部属性值,使得我们的应用程序更加灵活和可配置。
-
@ConfigurationProperties:这个注解用于将配置文件中的属性绑定到一个Java对象上。
以下是一个使用@ConfigurationProperties注解的示例:首先,在配置文件(例如application.properties或application.yml)中定义属性:
在application.properties中:
或者在application.yml中:
接下来,创建一个Java类并使用@ConfigurationProperties注解将属性绑定到该类上:
我们创建了一个名为MyAppProperties的组件类,并在该类上添加@Component和@ConfigurationProperties注解。@Component注解表示它是一个被Spring管理的Bean,@ConfigurationProperties注解表示将外部属性绑定到该类上。
通过@ConfigurationProperties注解的prefix属性,我们指定了属性的前缀为"my.app",即绑定以"my.app"开头的属性。
然后,在MyAppProperties类中定义了两个与配置文件中属性对应的字段:name和version,并提供了相应的getter和setter方法。
最后,我们重写了toString()方法,用于打印属性的值。
现在,我们可以在其他组件中使用MyAppProperties类来访问绑定的属性值。
例如,假设我们有一个名为MyComponent的组件类,需要使用MyAppProperties中的属性:
在MyComponent类中,我们使用@Autowired注解将MyAppProperties自动装配到私有的appProperties字段上。然后,我们定义了一个printAppInfo()方法,用于打印应用程序的名称和版本信息,从MyAppProperties中获取相应的属性值。
通过以上配置,当调用printAppInfo()方法时,它会打印出绑定的属性值:"Name: My Application"和"Version: 1.0.0"。
@ConfigurationProperties注解提供了一种方便的方式来将外部属性绑定到Java对象上,使得我们可以轻松地访问和管理配置属性。
-
@EnableConfigurationProperties:这个注解用于启用@ConfigurationProperties注解。
首先,创建一个被@ConfigurationProperties注解标记的Java类,例如MyAppProperties:
我们创建了一个名为MyAppProperties的组件类,并在该类上添加@Component和@ConfigurationProperties注解。@Component注解表示它是一个被Spring管理的Bean,@ConfigurationProperties注解表示将外部属性绑定到该类上。
通过@ConfigurationProperties注解的prefix属性,我们指定了属性的前缀为"my.app",即绑定以"my.app"开头的属性。
然后,在MyAppProperties类中定义了两个与配置文件中属性对应的字段:name和version,并提供了相应的getter和setter方法。
接下来,在启动类(通常是带有@SpringBootApplication注解的类)中使用@EnableConfigurationProperties注解启用@ConfigurationProperties注解标记的类:
我们在@SpringBootApplication注解上添加@EnableConfigurationProperties注解,并传入要启用的@ConfigurationProperties注解标记的类,即MyAppProperties.class。这样,Spring容器会自动将MyAppProperties类作为Bean注册到容器中,并启用属性绑定功能。
现在,我们可以在其他组件中使用@Autowired注解将MyAppProperties类自动装配,并访问绑定的属性值。
例如,假设我们有一个名为MyComponent的组件类,需要使用MyAppProperties中的属性:
在MyComponent类中,我们使用@Autowired注解将MyAppProperties自动装配到私有的appProperties字段上。然后,我们定义了一个printAppInfo()方法,用于打印应用程序的名称和版本信息,从MyAppProperties中获取相应的属性值。
当调用printAppInfo()方法时,它会打印出绑定的属性值:"Name: My Application"和"Version: 1.0.0"。
@EnableConfigurationProperties注解使得我们可以方便地启用@ConfigurationProperties注解标记的类,并将其作为Bean注册到Spring容器中,从而实现属性绑定和访问。
-
@Bean:这个注解用于声明一个由Spring容器管理的Bean。
首先,创建一个Java类,例如MyBean:我们创建了一个名为MyBean的普通Java类,它有一个name属性、构造方法和相应的getter和setter方法。
接下来,在配置类中使用@Bean注解声明和配置MyBean:
我们创建了一个名为AppConfig的配置类,并在该类上添加@Configuration注解。然后,我们在配置类中使用@Bean注解来声明并配置一个名为myBean的Bean。
在myBean方法中,我们返回了一个新的MyBean对象,并传入构造方法参数"Example Bean"。
通过这样的配置,Spring容器会将myBean方法返回的对象作为Bean注册到容器中。
现在,我们可以在其他组件中使用@Autowired注解将myBean对象自动装配,并使用其功能。
例如,假设我们有一个名为MyComponent的组件类,需要使用myBean对象:
以上是一些常见的Spring Boot Web开发使用到的注解,当然还有很多其他的注解可以用来实现更复杂的功能。使用这些注解可以帮助我们快速构建和配置Web应用程序,提高开发效率。