org.springframework.stereotype
包是 Spring Framework 的一个核心包,它包含了一组用于标注类,并将其声明为 Spring 管理的组件(Bean)的注解。 这些注解可以帮助 Spring 容器自动扫描、注册和管理 Bean,简化了 Spring 应用程序的配置。
以下是 org.springframework.stereotype
包下常用的注解,并附带详细的解释和使用场景:
1. @Component
-
作用: 将一个类声明为 Spring 组件(Bean)。
-
原理:
@Component
是一个通用的注解,表示一个类可以被 Spring 容器管理。 Spring 容器会自动扫描带有@Component
注解的类,并将其实例化为 Bean,注册到 IoC 容器中。 -
使用场景:
- 用于标记任何 Spring 管理的组件,没有明确的角色划分时,可以使用
@Component
。
- 用于标记任何 Spring 管理的组件,没有明确的角色划分时,可以使用
-
示例:
import org.springframework.stereotype.Component; @Component // 声明 MyService 为 Spring 组件 public class MyService { public void doSomething() { System.out.println("MyService is doing something..."); } }
2. @Service
-
作用: 将一个类声明为服务层组件(Service Layer Component)。
-
原理:
@Service
是@Component
的一个特化版本 (Specialized Version)。 它的作用与@Component
相同,但它用于更清晰地表达组件在应用架构中的角色,即服务层。 -
使用场景:
- 用于标记服务层类,封装业务逻辑。
-
示例:
import org.springframework.stereotype.Service; @Service // 声明 MyService 为服务层组件 public class MyService { public void doSomething() { System.out.println("MyService is doing something..."); } }
3. @Repository
-
作用: 将一个类声明为数据访问层组件(Data Access Layer Component)。
-
原理:
@Repository
也是@Component
的一个特化版本。 它用于更清晰地表达组件在应用架构中的角色,即数据访问层。 -
使用场景:
- 用于标记数据访问层类,负责与数据库或其他数据源进行交互。
@Repository
注解还可以启用 Spring 的PersistenceExceptionTranslationPostProcessor
,将数据访问相关的异常转换为 Spring 的统一数据访问异常体系 (DataAccessException
),简化异常处理。
-
示例:
import org.springframework.stereotype.Repository; @Repository // 声明 MyRepository 为数据访问层组件 public class MyRepository { public void saveData(String data) { System.out.println("Saving data to database: " + data); } }
4. @Controller
-
作用: 将一个类声明为控制器组件(Controller Component)。
-
原理:
@Controller
也是@Component
的一个特化版本。 它用于更清晰地表达组件在应用架构中的角色,即控制器层。 -
使用场景:
- 用于标记控制器类,负责接收用户请求,调用服务层处理业务逻辑,并返回响应。
- 通常与
@RequestMapping
,@GetMapping
,@PostMapping
等注解一起使用,定义请求映射规则。
-
示例:
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller // 声明 MyController 为控制器组件 public class MyController { @RequestMapping("/hello") public String hello() { return "hello"; // 返回视图名称 } }
5. @RestController
-
作用: 将一个类声明为 REST 控制器组件(REST Controller Component)。
-
原理:
@RestController
是一个组合注解,它包含了@Controller
和@ResponseBody
两个注解。 -
使用场景:
- 用于标记 REST 控制器类,负责处理 RESTful Web 服务请求,并直接返回 JSON、XML 或其他格式的响应数据。
- 不需要手动添加
@ResponseBody
注解,方法的返回值会自动转换为响应体。
-
示例:
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController // 声明 MyRestController 为 REST 控制器组件 public class MyRestController { @GetMapping("/api/data") public String getData() { return "{\"message\": \"Hello from REST Controller!\"}"; // 返回 JSON 字符串 } }
6. @Scope
-
作用: 指定 Spring Bean 的作用域 (Scope)。
-
常用取值:
singleton
(默认): 单例模式,一个 Spring 容器中只有一个 Bean 实例。prototype
: 每次请求都会创建一个新的 Bean 实例。request
: 每个 HTTP 请求创建一个新的 Bean 实例 (仅在 Web 应用中使用)。session
: 每个 HTTP 会话创建一个新的 Bean 实例 (仅在 Web 应用中使用)。application
: 在整个 Web 应用中创建一个 Bean 实例 (仅在 Web 应用中使用)。websocket
: 每一个WebSocket会话创建一个新的Bean 实例 (仅在WebSocket应用中使用)- 自定义作用域:可以定义自定义的作用域。
-
使用场景:
- 根据 Bean 的生命周期需求选择合适的作用域。
-
示例:
import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @Component @Scope("prototype") // 声明 MyPrototypeBean 为 prototype 作用域 public class MyPrototypeBean { // ... }
7. @Lazy
-
作用: 指定 Bean 是否延迟初始化 (Lazy Initialization)。
-
原理: 如果一个 Bean 被标记为
@Lazy
,那么 Spring 容器在启动时不会立即创建该 Bean 的实例,而是在第一次使用该 Bean 时才创建。 -
使用场景:
- 延迟加载不常用的 Bean,减少应用启动时间。
- 解决循环依赖问题。
-
示例:
import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @Component @Lazy // 声明 MyLazyBean 延迟初始化 public class MyLazyBean { public MyLazyBean() { System.out.println("MyLazyBean is being initialized..."); // 在第一次使用时才输出 } }
8. @Indexed
(Spring 5)
- 作用: 指示组件有资格进行类型索引。
- 原理: Spring 5 引入的注解,主要用于提高 Spring 组件扫描的性能。 通过在组件上添加
@Indexed
注解,可以使 Spring 容器在扫描组件时,将该组件的信息添加到索引中,从而加快后续的查找速度。 - 使用场景:
- 主要用于 Spring 内部优化, 开发者一般不需要直接使用。
- 对于大型项目,可以提升Spring 容器的启动速度。
- 注意
- 需要引入
org.springframework:spring-context-indexer
依赖。
- 需要引入
9. @Configuration
(虽然在 org.springframework.context.annotation
包下,但与 @Component
有着密切关系)
- 作用: 将一个类声明为配置类 (Configuration Class)。
- 原理:
@Configuration
类是 Spring Boot 应用的核心组成部分,它用于定义 Bean、配置应用程序的行为。 Spring 容器会自动扫描带有@Configuration
注解的类,并将其实例化为配置对象。 - 使用场景:
- 定义 Bean:在配置类中使用
@Bean
注解定义 Bean。 - 配置应用程序的行为:例如配置数据源、事务管理器、消息队列等。
- 引入其他的配置类:可以使用
@Import
注解引入其他的配置类。
- 定义 Bean:在配置类中使用
- 注意事项:
@Configuration
类通常与@Bean
、@ComponentScan
、@Import
等注解一起使用。@Configuration
类的方法可以被 Spring AOP 代理,因此在方法内部调用其他@Bean
方法时,会从 Spring 容器中获取 Bean 实例,而不是每次都创建一个新的实例。
总结
org.springframework.stereotype
包下提供的注解是构建 Spring 应用的基础,它们用于标记不同类型的组件,并将这些组件纳入 Spring 容器的管理。
@Component
: 用于标记通用的组件。@Service
: 用于标记服务层组件。@Repository
: 用于标记数据访问层组件。@Controller
: 用于标记控制器组件(Spring MVC)。@RestController
: 用于标记 REST 控制器组件(Spring MVC)。@Scope
: 用于指定 Bean 的作用域。@Lazy
: 用于指定 Bean 是否延迟初始化。@Indexed
: 用于在编译时为组件创建索引,提高组件扫描的性能.- 虽然
@Configuration
在org.springframework.context.annotation
包下, 但是仍然需要理解其作用和@Component
的区别。