在 Spring Boot 中,Bean 作用域是指 Spring 容器如何管理 Bean 的生命周期及其实例化的方式。Spring Boot 支持多种 Bean 作用域,包括以下几种:
单例作用域(Singleton Scope):每个容器中只存在一个 Bean 实例,所有请求该 Bean 的请求都返回同一个实例。这是 Spring Boot 默认的作用域。
原型作用域(Prototype Scope):每次请求该 Bean 时都会创建一个新的实例,每个实例之间相互独立。
会话作用域(Session Scope):每个会话(Session)中只存在一个 Bean 实例,不同会话之间的 Bean 实例是相互独立的。
请求作用域(Request Scope):每个请求(Request)中只存在一个 Bean 实例,不同请求之间的 Bean 实例是相互独立的。
全局会话作用域(Global Session Scope):类似于会话作用域,但是该作用域仅在基于 Portlet 的 Web 应用程序中使用。
应用程序作用域(Application Scope):类似于单例作用域,但是该作用域仅在基于 Portlet 的 Web 应用程序中使用。
下面是一个使用 Bean 作用域的示例代码,展示了如何在 Spring Boot 中配置 Bean 的作用域:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
@Configuration
public class MyConfig {
@Bean
@Scope("singleton")
public MySingletonBean singletonBean() {
return new MySingletonBean();
}
@Bean
@Scope("prototype")
public MyPrototypeBean prototypeBean() {
return new MyPrototypeBean();
}
// 其他作用域的 Bean 定义类似,这里不再赘述
}
在上述代码中,我们创建了一个 MyConfig
配置类,并定义了两个 Bean,分别是单例作用域和原型作用域的 Bean。在 singletonBean()
方法中,我们使用 @Scope
注解指定了 Bean 的作用域为单例作用域,这意味着每个容器中只存在一个 MySingletonBean
实例。在 prototypeBean()
方法中,我们使用 @Scope
注解指定了 Bean 的作用域为原型作用域,这意味着每次请求 Bean 时都会创建一个新的 MyPrototypeBean
实例。
需要注意的是,Spring Boot 中还支持自定义的 Bean 作用域,可以通过实现 org.springframework.beans.factory.config.Scope
接口来创建自定义的 Bean 作用域。此外,还可以使用 @Scope
注解的 proxyMode
属性来指定 Bean 的代理模式,以解决某些特定情况下的 Bean 作用域问题。
当我们在 Spring Boot 应用程序中定义一个 Bean 时,Spring 容器会负责管理该 Bean 的生命周期。在 Bean 的生命周期中,Spring 容器会负责执行 Bean 的实例化、属性赋值、初始化、使用和销毁等阶段。
下面是 Bean 生命周期中各个阶段的详细介绍:
实例化(Instantiation):在实例化阶段,Spring 容器根据 Bean 的定义信息创建 Bean 实例。根据 Bean 的作用域不同,Spring 容器可以创建多个 Bean 实例或仅创建一个 Bean 实例。
属性赋值(Populate):在属性赋值阶段,Spring 容器将 Bean 的属性值注入到 Bean 实例中,包括依赖注入等。属性赋值可以通过构造函数注入、Setter 方法注入等方式实现。
初始化(Initialization):在初始化阶段,Spring 容器调用 Bean 的初始化方法,可以自定义初始化方法。初始化方法可以通过 @PostConstruct
注解或实现 InitializingBean
接口来实现。
使用(In Use):在使用阶段,Bean 可以被其他组件使用。对于单例作用域的 Bean,它们的使用阶段一直持续到应用程序关闭,而对于其他作用域的 Bean,它们的使用阶段只在特定的作用域范围内。
销毁(Destruction):当 Bean 不再被使用时,Spring 容器调用 Bean 的销毁方法,可以自定义销毁方法。销毁方法可以通过 @PreDestroy
注解或实现 DisposableBean
接口来实现。
需要注意的是,Bean 的生命周期可以受到 Bean 之间的依赖关系、作用域、初始化和销毁方法等影响,因此在定义 Bean 的时候需要注意这些因素。此外,Spring Boot 还提供了一些扩展点,例如 BeanPostProcessor,可以在 Bean 生命周期的不同阶段添加自定义逻辑。通过这些扩展点,我们可以更加灵活地管理 Bean 的生命周期。
当然,下面是一些常用的 Spring Boot 注解,并且按照它们的功能进行分类:
@SpringBootApplication
:标记一个 Spring Boot 应用程序的主类,通常位于应用程序的顶层包中,用来启动 Spring 应用程序的自动配置、组件扫描和 Spring Boot 特性。此注解包含了以下三个注解:
`@Configuration`:标记一个类为配置类,通常用于定义 Bean。
`@ComponentScan`:指定要扫描的包和类,用于自动注册 Bean。
`@EnableAutoConfiguration`:启用自动配置,自动配置基于类路径上的类和其他 Bean 的存在,可以根据需求进行排除或包含。
@Component
:标记一个类为一个组件,通常用于自动扫描和注册 Bean。
@Bean
:标记一个方法为一个组件,通常用于自动扫描和注册 Bean。
@Service
:标记一个类为一个服务,通常用于标记业务逻辑层的实现类。
@Controller
:标记一个类为一个控制器,通常用于标记控制层的实现类。
@Repository
:标记一个类为一个持久层的Bean,用于数据库的访问操作。
@Autowired
:默认匹配方式为byType,无法匹配时byName。Spring内置。
@Resource
:默认匹配方式为byName,无法匹配时byType。JDK内置。
@Inject
:默认匹配方式为byType,无法匹配时byName。JDK内置。
@Qualifier
:用于指定依赖注入时的 Bean 名称,可以与 @Autowired、@Resource、@Inject一起使用。
@Value
:可以将配置文件中的值注入到 Bean 的属性中。
@ResponseBody
:用于将方法的返回值转换为 HTTP 响应体。
@RestController
:标记一个类为 Restful Web 服务的控制器,通常用于定义处理 HTTP 请求的方法。此注解相当于@Controller+@ResponseBody。
@RequestMapping
:定义处理 HTTP 请求的方法的映射路径和 HTTP 方法。
@GetMapping
:定义处理 HTTP GET 请求的方法的映射路径。
@PostMapping
:定义处理 HTTP POST 请求的方法的映射路径。
@PutMapping
:定义处理 HTTP PUT 请求的方法的映射路径。
@DeleteMapping
:定义处理 HTTP DELETE 请求的方法的映射路径。
@PathVariable
:用于将 URL 中的参数绑定到方法的参数上。
@RequestParam
:用于将查询参数绑定到方法的参数上。
@RequestBody
:用于将 HTTP 请求体绑定到方法的参数上。
@RequestParam 和 @RequestBody 是 Spring Boot 中常用的两种注解,它们的作用不同,具体区别如下:
@RequestParam 用于从 URL 中获取请求参数,常用于 GET 请求;@RequestBody 用于从请求体中获取请求参数,常用于 POST、PUT、DELETE 等请求。
@RequestParam 可以接收基本数据类型、包装类、字符串等类型的参数;@RequestBody 可以接收任意类型的参数,包括自定义类、集合等。
@RequestParam 通过 URL 中的查询字符串传递参数,例如:http://example.com/user?id=123 ↗;@RequestBody 则是通过请求体传递参数,请求体中的参数格式可以是 JSON、XML、文本等格式。
@RequestParam 接收到的参数会被 Spring Boot 自动进行类型转换,例如将字符串转换成整数、日期等类型;@RequestBody 接收到的参数则需要手动进行解析和转换。
@RequestParam 通常用于获取单个或少量的请求参数,例如获取用户 ID、页码等;@RequestBody 则通常用于接收表单、JSON 等格式的请求数据,例如提交表单、上传文件等。
需要注意的是,@RequestParam 和 @RequestBody 并不是互相排斥的,它们可以同时使用,例如在 POST 请求中,@RequestParam 可以用来获取 URL 中的查询参数,@RequestBody 则可以用来接收请求体中的参数。
@RequestParam 和 @PathVariable 都是 Spring Boot 中常用的用于处理 HTTP 请求参数的注解,它们有以下区别:
@RequestParam 注解用于从请求参数中获取值,请求参数通常是通过 URL 的查询字符串(例如:?name=value)传递的;而 @PathVariable 注解用于从 URI 中获取值,URI 通常是通过路径参数(例如:/users/{id})传递的。
@RequestParam 注解可以接收基本数据类型、包装类、字符串等类型的参数;而 @PathVariable 注解通常接收字符串类型的参数,可以自动进行类型转换。
@RequestParam 通常用于获取少量的查询参数,例如获取用户 ID、页码等;而 @PathVariable 则通常用于获取 URL 中的路径参数,例如获取用户 ID、订单号等。
需要注意的是,@RequestParam 和 @PathVariable 并不是互相排斥的,它们可以同时使用,例如在 RESTful 接口中,可以使用 @PathVariable 获取路径参数,同时使用 @RequestParam 获取查询参数。
@Transactional
:标记一个方法或类为事务性操作,用于控制事务的提交和回滚。
@Entity
:标记一个类为实体类,通常用于标记持久化对象。
@Table
:定义实体类所映射的表名。
@Column
:定义实体类属性所映射的列名。
以上是一些常用的 Spring Boot 注解,这些注解可以帮助我们快速开发应用程序,并且使得我们的代码更加简洁和易于维护。当然,还有很多其他的注解,可以根据实际需求选择使用。