目录
一、Spring Web MVC 与 Spring Bean 注解
三、Spring Dependency Inject 与 Bean Scops注解
当谈到Spring Boot时,注解是其中一个非常重要的部分。它们极大地简化了开发过程,提高了代码的可读性和可维护性。在本文章中,我将介绍一些常用的Spring Boot注解,并解释它们的作用和用法。
@SpringBootApplication
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
@SpringBootApplication
注解标记了一个类作为Spring Boot应用的入口点。它整合了 @Configuration
、@EnableAutoConfiguration
和 @ComponentScan
注解,简化了配置。通常情况下,你只需在应用的主类上添加这个注解即可启动一个基本的Spring Boot应用。
@RestController
当使用@RestController注解标记一个类时,它将成为一个控制器类,并且其中的方法将返回数据而不是视图。这里是一个简单的使用示例:
@RestController
@RequestMapping("/api")
public class HelloController {
@GetMapping("/hello")
public String sayHello() {
return "Hello, World!";
}
}
在上面的示例中,我们使用 @RestController
注解标记 HelloController
类,这意味着它将处理来自"/api"路径下的请求。在 HelloController
中,我们使用 @GetMapping
注解来指定处理GET请求的方法,并且该方法会返回一个字符串 "Hello, World!"。由于我们使用了 @RestController
注解,返回的字符串将直接作为HTTP响应的内容,而不会被解释为视图名称。
当客户端发送GET请求到"/api/hello"时,sayHello
方法将会被调用,并且它的返回值 "Hello, World!" 将会作为响应的主体内容返回给客户端。
一、Spring Web MVC 与 Spring Bean 注解
Spring Web MVC 注解
@RequestMapping
@RequestMapping注解的主要用途是将Web请求与请求处理类中的方法进行映射。Spring MVC和Spring WebFlux都通过RquestMappingHandlerMapping和RequestMappingHndlerAdapter两个类来提供对@RequestMapping注解的支持。
@RequestMapping注解对请求处理类中的请求处理方法进行标注;@RequestMapping注解拥有以下的六个配置属性:
- value:映射的请求URL或者其别名
- method:兼容HTTP的方法名
- params:根据HTTP参数的存在、缺省或值对请求进行过滤
- header:根据HTTP Header的存在、缺省或值对请求进行过滤
- consume:设定在HTTP请求正文中允许使用的媒体类型
- product:在HTTP响应体中允许使用的媒体类型
提示:在使用@RequestMapping之前,请求处理类还需要使用@Controller或@RestController进行标记
下面是使用@RequestMapping的两个示例:
示例1:基本的URL映射
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class HelloController {
@RequestMapping("/hello")
@ResponseBody
public String hello() {
return "Hello, World!";
}
}
在这个示例中,我们创建了一个名为HelloController的控制器类。通过@RequestMapping注解,我们指定了/hello路径与hello()方法的映射关系。当应用收到对“/hello”路径的HTTP GET请求时,将调用hello()方法并返回“Hello, World!”的字符串作为响应。
示例2:带有HTTP请求方法限定的URL映射
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class GreetingController {
@RequestMapping(value = "/greet", method = RequestMethod.POST)
@ResponseBody
public String greet() {
return "Greetings!";
}
}
在这个示例中,我们定义了一个带有限定HTTP请求方法的URL映射。通过@RequestMapping注解的value属性指定了/greet路径与greet()方法的映射关系,并且通过method属性限定了只有HTTP POST请求才会触发该方法。当应用收到对“/greet”路径的HTTP POST请求时,将调用greet()方法并返回“Greetings!”的字符串作为响应。
这两个示例展示了如何使用@RequestMapping注解来映射HTTP请求到控制器的处理方法上,从而实现了基本的URL映射和带有HTTP请求方法限定的URL映射。
@RequestBody
当在Spring Boot中使用@RestController时,@RequestBody注解用于将HTTP请求的请求体绑定到方法参数上。以下是一个简单的示例,演示了如何使用@RequestBody注解。
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ExampleController {
@PostMapping("/api/user")
public String createUser(@RequestBody User user) {
// 在这里可以对接收到的用户数据进行处理
return "User created: " + user.getUsername();
}
}
在这个示例中,我们创建了一个名为ExampleController的REST控制器类。在createUser()方法中,我们使用@PostMapping注解来指定处理HTTP POST请求的/api/user路径。通过@RequestBody注解,我们将请求体中的JSON数据映射到user参数上,其中User是一个自定义的Java类,用于表示用户信息。
假设发送以下JSON数据作为POST请求的请求体:
{
"username": "john_doe",
"email": "john@example.com"
}
当应用收到符合条件的HTTP POST请求时,Spring Boot将自动将JSON数据映射到User对象,并传递给createUser()方法。方法内部可以通过User对象来访问和处理接收到的用户数据,然后返回相应的响应信息。
通过这个示例,你可以看到如何使用@RequestBody注解来接收并处理JSON格式的请求体数据。这种方式非常适合用于处理RESTful API中的POST请求,从而实现了客户端与服务器端之间的数据传输和交互。
@RequestBody在处理请求方法的参数列表中使用,它可以将请求主体中的参数绑定到一个对象中,请求主体参数是通过HttpMessageConverter传递的,根据请求主体中的参数名与对象的属性名进行匹配并绑定值。此外,还可以通过@Valid注解对请求主体中的参数进行校验。
@GetMapping
@GetMapping注解用于处理HTTP GET请求,并将请求映射到具体的处理方法中。具体来说,@GetMapping是一个组合注解,它相当于是@RequestMapping(method=RequestMethod.GET)的快捷方式。
下面是@GetMapping的一个使用示例:
@RestController
public class HelloController {
@GetMapping("/hello")
public String sayHello(){
return "Hello, world!";
}
}
@PostMapping
@PostMapping注解用于处理HTTP POST请求,并将请求映射到具体的处理方法中。@PostMapping与@GetMapping一样,也是一个组合注解,它相当于是@RequestMapping(method=HttpMethod.POST)的快捷方式。
下面是使用@PostMapping的一个示例:
@RestController
@RequestMapping("/api")
public class MyController {
@PostMapping("/user")
public ResponseEntity<String> createUser(@RequestBody User user) {
// 处理创建用户的逻辑
// ...
return ResponseEntity.ok("User created successfully");
}
}
在上面的示例中,我们使用@RestController注解标记该类为控制器,并使用@RequestMapping注解指定了根路径为"/api"。 然后,我们使用@PostMapping注解来标记createUser方法,该方法处理POST请求并接受一个User对象作为请求体(使用@RequestBody注解进行绑定)。 在方法体内,我们可以编写处理创建用户的逻辑,处理完成后返回一个包含成功消息的ResponseEntity对象。
需要注意的是,根据具体的业务需求,可以根据需要修改方法参数和返回值类型。
@PutMapping
@PutMapping注解用于处理HTTP PUT请求,并将请求映射到具体的处理方法中,@PutMapping是一个组合注解,相当于是@RequestMapping(method=HttpMethod.PUT)的快捷方式。
下面是使用@PutMapping的一个示例:
@RestController
@RequestMapping("/api")
public class UserController {
private Map<Long, User> userMap = new HashMap<>();
@PutMapping("/user/{id}")
public ResponseEntity<String> updateUser(@PathVariable Long id, @RequestBody User updatedUser) {
User existingUser = userMap.get(id);
if (existingUser != null) {
// 更新用户信息
existingUser.setName(updatedUser.getName());
existingUser.setEmail(updatedUser.getEmail());
userMap.put(id, existingUser);
return ResponseEntity.ok("User updated successfully");
} else {
return ResponseEntity.notFound().build();
}
}
}
在上述示例中,我们使用 @RestController
注解将 UserController
类标记为控制器类,并指定根路径为 "/api"。 然后,我们使用 @PutMapping
注解标记了 updateUser
方法,该方法用于处理 PUT 请求,并接受路径参数 id
和 User
对象作为请求体(使用 @RequestBody
注解进行绑定)。 在方法体中,我们首先根据 id
从 userMap
中获取现有用户信息,然后根据请求中的更新信息更新用户数据。如果用户存在,我们更新用户信息并返回一个包含成功消息的 ResponseEntity
对象;如果用户不存在,我们返回一个状态码为 404 的响应。
请注意,根据实际需求,您可以根据需要修改方法参数和返回值类型,以及实际的业务逻辑处理。
@DeleteMapping
@DeleteMapping注解用于处理HTTP DELETE请求,并将请求映射到删除方法中。@DeleteMapping是一个组合注解,它相当于是@RequestMapping(method=HttpMethod.DELETE)的快捷方式。
下面是使用@DeleteMapping的一个示例:
@RestController
public class ExampleController {
@DeleteMapping("/api/users/{userId}")
public String deleteUser(@PathVariable("userId") Long userId) {
// 处理删除用户的逻辑
//……
return "User deleted successfully";
}
}
在上面的示例中,我们使用@DeleteMapping
注解来处理删除用户的请求。请求的URL路径为/api/users/{userId}
,其中{userId}
是路径参数,表示要删除的用户ID。通过@PathVariable
注解,我们可以将路径参数绑定到方法的参数上。在方法体内,我们可以编写删除用户的逻辑。
@ResponseBody
@ResponseBody会自动将控制器中方法的返回值写入到HTTP响应中。特别的,@ResponseBody注解只能用在被@Controller注解标记的类中。如果在被@RestController标记的类中,则方法不需要使用@ResponseBody注解进行标注。@RestController相当于是@Controller和@ResponseBody的组合注解。
下面是使用该注解的一个示例
@RestController
@RequestMapping("/api")
public class UserController {
@GetMapping("/user/{id}")
@ResponseBody
public User getUserById(@PathVariable Long id) {
// 从数据库或其他数据源中获取用户信息
User user = userRepository.findById(id);
return user;
}
}
在上述示例中,我们使用 @RestController
注解将 UserController
类标记为控制器类,并指定根路径为 "/api"。 然后,我们使用 @GetMapping
注解标记了 getUserById
方法,该方法用于处理 GET 请求,并接受路径参数 id
。同时,我们使用 @ResponseBody
注解将返回的 User
对象直接作为 HTTP 响应的主体部分返回。
需要注意的是,在使用 @RestController
注解标记的类中,所有方法的返回值将默认被解释为 HTTP 响应的主体部分。因此,使用 @ResponseBody
注解在这种情况下并非必需,但它可以作为对方法行为的明确标识,增强代码的可读性。
@PathVariable
@PathVariable注解是将方法中的参数绑定到请求URI中的模板变量上。可以通过@RequestMapping注解来指定URI的模板变量,然后使用@PathVariable注解将方法中的参数绑定到模板变量上。
特别地,@PathVariable注解允许我们使用value或name属性来给参数取一个别名。下面是使用此注解的一个示例:
@RestController
public class UserController {
@GetMapping("/users/{userId}/orders/{orderId}")
public String getOrderDetails(
@PathVariable("userId") Long userId,
@PathVariable("orderId") String orderNumber) {
return "User " + userId + " has ordered the product with order number: " + orderNumber;
}
}
在这个示例中,我们创建了一个名为UserController的RESTful风格的控制器类,并使用@GetMapping注解来指定处理HTTP GET请求的路径。在getOrderDetails()方法中,我们使用@PathVariable注解的value属性分别将路径变量userId和orderId绑定到方法的参数上,并指定了它们的别名。
假设向应用发送HTTP GET请求:/users/123/orders/456,那么应用将会调用getOrderDetails()方法,并返回类似“User 123 has ordered the product with order number: 456”的内容作为HTTP响应。
通过这个示例,你可以看到如何使用@PathVariable注解的value属性来为路径变量指定别名,以提高代码的可读性和表达性。这种方式非常适合在RESTful API的场景中,对路径变量进行更具有描述性的命名。
@RequestParam
@RequestParam注解用于将方法的参数与Web请求的传递的参数进行绑定。使用@RequestParam可以轻松的访问HTTP请求参数的值。
下面是使用该注解的代码示例:
@RestController
public class HelloController {
@GetMapping("/hello")
public String sayHello(@RequestParam("name") String name){
return "Hello,"+ name + "!";
}
}
在这个示例中,我们创建了一个名为HelloController的RESTful风格的控制器类,并使用@GetMapping注解来指定处理HTTP GET请求的/hello路径。在sayHello()方法中,我们使用@RequestParam("name")注解将请求参数name绑定到方法的参数上。
假设向应用发送HTTP GET请求:/hello?name=John,那么应用将会调用sayHello()方法,并返回“Hello, John!”作为HTTP响应的内容。
通过这个示例,你可以看到如何使用@RequestParam注解来从请求中获取参数,然后在方法中使用这些参数进行逻辑处理。这种方式非常适合在处理RESTful API的场景中,根据请求参数来动态生成响应内容。
@Controller
@Controller是@Component注解的一个延伸,
Spring
会自动扫描并配置被该注解标注的类。此注解用于标注Spring MVC的控制器。下面是使用此注解的示例代码:
@Controller
public class GreetingController {
@GetMapping("/greet")
public String greet(@RequestParam String name, Model model) {
model.addAttribute("name", name);
return "greetView";
}
}
在这个示例中,我们创建了一个名为GreetingController的传统MVC控制器类,并使用@Controller注解标记该类。在greet()方法中,我们使用@GetMapping注解来指定处理HTTP GET请求的/greet路径。方法的参数name使用@RequestParam注解表示从请求的查询参数中获取值,同时使用Model对象向视图传递数据。
假设向应用发送HTTP GET请求:/greet?name=John,那么应用将会调用greet()方法,并将"name"属性添加到Model中,然后返回"greetView"作为视图名称。
在这个示例中,返回值"greetView"表示视图的逻辑名称,在Spring Boot的视图解析器中会将其解析为实际的视图模板,最终生成HTTP响应的内容。通过这种方式,你可以轻松地创建传统的MVC控制器,并与视图层进行交互。
@RestController
@RestController是在Spring 4.0开始引入的,这是一个特定的控制器注解。此注解相当于@Controller和@ResponseBody的快捷方式。当使用此注解时,不需要再在方法上使用@ResponseBody注解。
下面是使用此注解的示例代码
在这个示例中,我们创建了一个名为GreetingController的RESTful风格的控制器类,并使用@RestController注解标记该类。在greet()方法中,我们使用@GetMapping注解来指定处理HTTP GET请求的/greet路径。方法的参数name使用@RequestParam注解表示从请求的查询参数中获取值。
@RestController
public class GreetingController {
@GetMapping("/greet")
public String greet(@RequestParam String name) {
return "Hello, " + name + "!";
}
}
在这个示例中,我们创建了一个名为GreetingController的RESTful风格的控制器类,并使用@RestController注解标记该类。在greet()方法中,我们使用@GetMapping注解来指定处理HTTP GET请求的/greet路径。方法的参数name使用@RequestParam注解表示从请求的查询参数中获取值。
假设向应用发送HTTP GET请求:/greet?name=John,那么应用将会调用greet()方法,并返回“Hello, John!”作为HTTP响应的内容。
通过这个示例,你可以看到当使用@RestController注解后,不需要显式地指定返回的内容类型,方法的返回值会直接作为HTTP响应的内容返回给客户端。这使得编写RESTful风格的控制器变得更加简洁和方便。
二、Spring Bean 注解
在本小节中,主要列举与Spring Bean相关的4个注解以及它们的使用方式。
@ComponentScan
@ComponentScan注解用于配置Spring需要扫描的被组件注解注释的类所在的包。可以通过配置其basePackages属性或者value属性来配置需要扫描的包路径。value属性是basePackages的别名。此注解的用法如下:
@Component
@Component注解用于标注一个普通的组件类,它没有明确的业务范围,只是通知Spring被此注解的类需要被纳入到Spring Bean容器中并进行管理。此注解的使用示例如下:
@Component
public class MyComponent {
public void doSomething(){
//执行一些操作
}
}
在上述示例中,我们使用 @Component
注解标记了 MyComponent
类,这表示 MyComponent
类将由 Spring 容器进行管理,并且可以在其他组件中被注入和使用。
一旦使用 @Component
注解标记了一个类,Spring 容器将会扫描并识别这个类,并在启动时创建其实例,使其成为容器中的一个可用组件。之后,我们就可以在其他需要使用 MyComponent
的地方进行注入和调用。
除了 @Component
注解外,Spring 还提供了一系列其他的注解,如 @Service
、@Repository
和 @Controller
,它们分别用于标识服务类、数据访问类和控制器类,但它们的底层都是基于 @Component
注解实现的。
@Service
@Service注解是@Component的一个延伸(特例),它用于标注业务逻辑类。与@Component注解一样,被此注解标注的类,会自动被Spring所管理。下面是使用@Service注解的示例:
import org.springframework.stereotype.Service;
@Service
public class MyService {
public void doSomething() {
// 服务的实现细节
}
}
在上面的示例中,我们使用@Service
注解将MyService
类标记为一个服务类。这意味着Spring容器会自动扫描和检测到这个类,并在需要时将其实例化为Spring应用程序上下文的一部分。
@Repository
@Repository注解也是@Component注解的延伸,与@Component注解一样,被此注解标注的类会被Spring自动管理起来,@Repository注解用于标注DAO层的数据持久化类。此注解的用法如下:
import org.springframework.stereotype.Repository;
@Repository
public class UserRepository {
public User getUserById(Long id) {
// 从数据库中获取用户信息的逻辑
// 假设这里是通过 JDBC 或者 ORM 框架来实现的
User user = // 从数据库中获取用户信息的代码
return user;
}
public void saveUser(User user) {
// 将用户信息保存到数据库的逻辑
// 假设这里是通过 JDBC 或者 ORM 框架来实现的
}
}
在上述示例中,我们使用 @Repository
注解标记了 UserRepository
类,这表示 UserRepository
类将被 Spring 框架识别为数据访问对象,并且可以受益于 Spring 的事务管理和异常转换等特性。
在实际应用中,UserRepository
类通常会包含一些用于访问数据库的方法,比如获取用户信息、保存用户信息等。通过使用 @Repository
注解,Spring 框架会对 UserRepository
进行特殊处理,使得它可以参与 Spring 的事务管理、异常转换等工作。
总之,使用 @Repository
注解可以将一个数据访问对象标识为 Spring 框架管理的组件,从而让我们能够利用 Spring 的特性更加便捷地进行数据访问操作。
三、Spring Dependency Inject 与 Bean Scops注解
Spring DI注解
@Bean
@Bean注解主要的作用是告知Spring,被此注解所标注的类将需要纳入到Bean管理工厂中。示例如下:
@Configuration
public class AppConfig {
@Bean
public UserService userService() {
return new UserService();
}
}
在上述示例中,我们创建了一个名为 AppConfig
的配置类,并在其中定义了一个使用 @Bean
注解标记的方法 userService
。该方法返回一个 UserService
对象,表示我们希望将 UserService
对象交由 Spring 容器进行管理。
四、容器配置注解
@Autowired
@Autowired注解用于标记Spring将要解析和注入的依赖项。此注解可以作用在构造函数、字段和setter方法上。
作用于构造函数
下面是@Autowired注解标注构造函数的使用示例:
@Service
public class UserService {
private UserRepository userRepository;
@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
// 省略其他方法
}
在上述示例中,我们创建了一个名为 UserService
的服务类,并在构造函数上使用 @Autowired
注解标记了一个 UserRepository
类型的参数。这表示我们希望通过自动装配的方式将 UserRepository
对象注入到 UserService
类中。
总之,通过使用 @Autowired
注解,我们可以方便地实现依赖注入,让 Spring 容器自动处理对象之间的依赖关系,提高代码的可读性和可维护性。
作用于setter方法
当使用 @Autowired
注解标注 setter 方法时,它表示被注解的方法将会通过自动装配的方式来获取所需的依赖对象。
下面是@Autowired注解标注setter方法的示例代码:
@Service
public class UserService {
private UserRepository userRepository;
@Autowired
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
在上述示例中,我们创建了一个名为 UserService
的服务类,并在 setUserRepository
方法上使用 @Autowired
注解标注了一个 UserRepository
类型的参数。这表示我们希望通过自动装配的方式将 UserRepository
对象注入到 UserService
类中。
当 Spring 容器在创建 UserService
实例时,它会检查 setUserRepository
方法上的 @Autowired
注解,并尝试在容器中寻找匹配的 UserRepository
实例。如果找到了,就会将该实例自动注入到 UserService
中。
使用 @Autowired
注解标注 setter 方法是一种常见的依赖注入方式,它可以让 Spring 容器自动处理对象之间的依赖关系,使代码更加简洁和可读。
总之,通过在 setter 方法上使用 @Autowired
注解,我们可以方便地实现依赖注入,让 Spring 容器自动处理对象之间的依赖关系。
作用于字段
@Autowired注解标注字段是最简单的,只需要在对应的字段上加入此注解即可,示例代码如下:
@Component
public class UserService {
@Autowired
private UserRepository userRepository;
public List<User> getAllUsers() {
return userRepository.findAll();
}
}
在上面的示例中,我们使用@Autowired
注解将UserRepository
注入到UserService
类的字段中。这意味着Spring容器会自动检测到UserRepository
的实例,并将其注入到UserService
的字段中。这样,我们就可以在UserService
中使用UserRepository
来访问数据库,而不需要手动创建UserRepository
的实例。
@Primary
当系统中需要配置多个具有相同类型的bean时,@Primary可以定义这些Bean的优先级。下面将给出一个实例代码来说明这一特性:
@Configuration
public class AppConfig {
@Bean
@Primary
public MyService primaryMyService() {
return new MyServiceImpl1();
}
@Bean
public MyService myService() {
return new MyServiceImpl2();
}
@Autowired
private MyService myService;
}
在上面的示例中,我们定义了两个MyService
类型的Bean。一个是使用@Primary
注解标记的primaryMyService()
方法,另一个是普通的myService()
方法。当使用@Autowired
注解注入MyService
类型的Bean时,Spring容器会优先选择使用primaryMyService()
方法创建的Bean,并将其注入到myService
属性中。如果primaryMyService()
方法没有创建成功(例如因为依赖其他Bean失败),则Spring容器会尝试使用myService()
方法创建的Bean进行注入。
需要注意的是,使用@Primary
注解时需要谨慎,确保只有一个Bean被标记为@Primary
,否则会导致注入失败。
五、Spring Boot注解
@SpringBootApplication
@SpringBootApplication注解是一个快捷的配置注解,在被它标注的类中,可以定义一个或多个Bean,并自动触发自动配置Bean和自动扫描组件。此注解相当于@Configuration、@EnableAutoConfiguration和@ComponentScan的组合。
在Spring Boot应用程序的主类中,就使用了此注解。示例代码如下:
@SpringBootApplicationpublic class Application{ public static void main(String [] args){ SpringApplication.run(Application.class,args); }}
@EnableAutoConfiguration
@EnableAutoConfiguration注解用于通知Spring,根据当前类路径下引入的依赖包,自动配置与这些依赖包相关的配置项。
总结
本次课程总结了Spring Boot中常见的各类型注解的使用方式,让大家能够统一的对Spring Boot常用注解有一个全面的了解。