scope详解

scope的分类

1.compile:默认值 他表示被依赖项目需要参与当前项目的编译,还有后续的测试,运行周期也参与其中,是一个比较强的依赖。打包的时候通常需要包含进去

2.test:依赖项目仅仅参与测试相关的工作,包括测试代码的编译和执行,不会被打包,例如:junit

3.runtime:表示被依赖项目无需参与项目的编译,不过后期的测试和运行周期需要其参与。与compile相比,跳过了编译而已。例如JDBC驱动,适用运行和测试阶段

4.provided:打包的时候可以不用包进去,别的设施会提供。事实上该依赖理论上可以参与编译,测试,运行等周期。相当于compile,但是打包阶段做了exclude操作

5.system:从参与度来说,和provided相同,不过被依赖项不会从maven仓库下载,而是从本地文件系统拿。需要添加systemPath的属性来定义路径

scope的依赖传递

A依赖B,B依赖C。当前项目为A,只当B在A项目中的scope,那么c在A中的scope是如何得知呢?

当C是test或者provided时,C直接被丢弃,A不依赖C;(排除传递依赖)

否则A依赖C,C的scope继承与B的scope


<think>我们正在讨论Spring框架中的@Scope注解。根据引用内容,@Scope注解用于定义bean的作用域。在Spring中,bean的作用域决定了bean实例的生命周期和创建方式。 引用[4]详细说明了@Scope注解的用法,并列举了常见的作用域类型: - `singleton`:默认作用域,整个IOC容器中只有一个实例,容器启动时就会创建(饿汉式)。 - `prototype`:多实例,每次获取bean时都会创建一个新的实例(懒汉式,在每次获取时才创建)。 - `request`:每个HTTP请求创建一个新的实例(仅Web应用)。 - `session`:每个HTTP会话创建一个实例(仅Web应用)。 引用[1]提到@Scope注解有两个属性:代理模式(proxyMode)和作用域(value)。代理模式用于解决作用域不一致的问题(例如,在单例bean中注入原型bean),代理模式选项包括: - `ScopedProxyMode.DEFAULT`:默认值,通常等同于`NO`。 - `ScopedProxyMode.NO`:不使用代理。 - `ScopedProxyMode.INTERFACES`:使用JDK动态代理(基于接口)。 - `ScopedProxyMode.TARGET_CLASS`:使用CGLIB代理(基于类)。 引用[3]展示了一个使用`SCOPE_PROTOTYPE`的代码示例:当作用域设置为prototype时,每次获取bean都会创建一个新实例。 引用[2]则提供了更多的使用场景和示例,包括单例和多例的演示,以及讨论了饿汉式和懒汉式的创建时机。 因此,我们可以总结如下: ### @Scope注解详解 `@Scope`注解用于指定Spring容器中Bean的作用域,它可以用在`@Component`、`@Bean`等注解的类或方法上。该注解有两个重要属性: 1. `value`(或`scopeName`):指定作用域的类型,如`singleton`、`prototype`等。 2. `proxyMode`:指定代理模式,用于解决作用域不一致的问题,如`ScopedProxyMode.INTERFACES`或`ScopedProxyMode.TARGET_CLASS`。 #### 作用域类型: 1. **singleton**(默认):单例模式,整个Spring IoC容器中只存在一个Bean实例。容器启动时即创建(饿汉式),后续每次获取都是同一个实例。 ```java @Scope("singleton") // 或 @Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON) ``` 2. **prototype**:多例模式,每次从容器中获取Bean时都会创建一个新的实例。容器启动时不会创建,而是在每次获取时创建(懒汉式)。 ```java @Scope("prototype") // 或 @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) ``` 3. **request**:每个HTTP请求创建一个新的实例(仅Web应用可用)。 4. **session**:每个HTTP会话创建一个实例(仅Web应用可用)。 5. **application**:整个Web应用的生命周期内只创建一个实例(仅Web应用可用)。 6. **websocket**:每个WebSocket会话创建一个实例(仅Web应用可用)。 #### 代理模式(proxyMode): 当在单例Bean中注入一个作用域较短的Bean(如prototype)时,由于单例Bean只初始化一次,它注入的原型Bean也就固定了。为了每次使用都能得到新的原型Bean,可以使用代理。代理模式选项: - `NO`:不创建代理(默认)。 - `INTERFACES`:使用JDK动态代理(要求目标Bean实现接口)。 - `TARGET_CLASS`:使用CGLIB代理(针对类代理,不需要实现接口)。 示例:在单例Bean中注入原型Bean并使用代理 ```java @Configuration public class AppConfig { @Bean @Scope("singleton") public SingletonBean singletonBean() { return new SingletonBean(); } @Bean @Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS) public PrototypeBean prototypeBean() { return new PrototypeBean(); } } ``` 这样,每次`singletonBean`调用`prototypeBean`时,都会得到一个新的`PrototypeBean`实例。 #### 使用场景: - 单例模式:适用于无状态的Bean,如工具类、服务类等。 - 多例模式:适用于有状态的Bean,如用户会话、购物车等需要隔离状态的场景。 - 自定义作用域:如线程作用域、自定义作用域(通过实现`Scope`接口)等。 此外,引用[4]还提到,对于prototype作用域的Bean,Spring容器不负责销毁,需要由调用者自行管理生命周期。 以上内容综合了多个引用的信息,对@Scope注解进行了详细解释。 §§相关问题§§ 1. @Scope注解的proxyMode属性在什么场景下必须使用? 2. 如何自定义一个Spring作用域? 3. 在Web应用中,request和session作用域的具体使用示例? 4. singleton和prototype作用域下,Bean的初始化和销毁方法有什么不同? </think>### @Scope注解详细解释 `@Scope`是Spring框架中用于定义Bean作用域的核心注解,主要控制Bean实例的创建方式、生命周期和作用范围。以下是详细解析: #### 1. **核心作用域类型** - **singleton(默认)** 单例模式,Spring容器中**只存在一个实例** ✅ 创建时机:IoC容器启动时立即创建(饿汉式) ✅ 获取方式:每次请求都返回同一个实例(`map.get()`) ```java @Scope("singleton") // 或 @Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON) ``` - **prototype** 多实例模式,**每次请求创建新实例** ✅ 创建时机:调用`getBean()`时创建(懒汉式) ✅ 生命周期:Spring不管理销毁,由GC回收 ```java @Scope("prototype") // 或 @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) ``` - **Web相关作用域** - `request`:每个HTTP请求创建新实例(如用户请求级数据) - `session`:每个用户会话创建新实例(如用户登录信息) - `application`:整个Web应用生命周期共享一个实例 #### 2. **代理模式(proxyMode)** 解决作用域不一致问题(如单例Bean引用原型Bean): ```java @Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS) ``` - **`ScopedProxyMode.NO`**:不启用代理(默认) - **`ScopedProxyMode.INTERFACES`**:基于JDK动态代理(需实现接口) - **`ScopedProxyMode.TARGET_CLASS`**:基于CGLIB代理(类级代理)[^1] #### 3. **典型使用场景** | 作用域 | 适用场景 | 示例 | |--------------|-----------------------------------|--------------------------| | `singleton` | 无状态服务、工具类、配置类 | `@Service`, `@Repository` | | `prototype` | 有状态对象(如用户会话) | 购物车、请求处理器 | | `request` | HTTP请求级数据封装 | 表单数据对象 | | `session` | 用户会话数据 | 登录凭证 | #### 4. **代码示例对比** ```java // 单例模式(默认) @Bean public Person singletonPerson() { return new Person("张三", 30); // 容器启动时创建 } // 多例模式 @Bean @Scope("prototype") public Person prototypePerson() { return new Person("李四", 25); // 每次getBean()时创建 } ``` #### 5. **生命周期差异** | 动作 | singleton | prototype | |--------------|-----------------|-----------------| | 实例创建时机 | 容器初始化时 | 调用getBean()时 | | 销毁管理 | 容器关闭时销毁 | Spring不管理 | | 内存占用 | 单实例低占用 | 多实例高占用 | > ⚠️ 注意:多例模式(prototype)需要谨慎使用,频繁创建可能引发内存泄漏[^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值