跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
Spring Bean作用域
”︁(章节)
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
= Spring Bean作用域 = == 介绍 == 在Spring框架中,'''Bean作用域'''(Bean Scope)定义了Bean实例的生命周期和可见范围。Spring IoC容器管理着这些Bean的创建、配置和管理方式,而作用域决定了Bean在应用程序中的共享方式。理解不同的作用域类型对于构建高效、可维护的Spring应用程序至关重要。 Spring提供了多种标准作用域,开发者还可以自定义作用域。每种作用域适用于不同的应用场景,例如单例模式适用于共享资源,而原型模式适用于每次请求都创建新实例的场景。 == 标准作用域 == Spring框架支持以下标准作用域: {| class="wikitable" |- ! 作用域类型 !! 描述 |- | <code>singleton</code> || (默认)每个Spring IoC容器中仅存在一个Bean实例。 |- | <code>prototype</code> || 每次请求Bean时都会创建一个新的实例。 |- | <code>request</code> || 每个HTTP请求创建一个Bean实例(仅适用于Web应用)。 |- | <code>session</code> || 每个HTTP会话创建一个Bean实例(仅适用于Web应用)。 |- | <code>application</code> || 整个Web应用共享一个Bean实例(类似于ServletContext)。 |- | <code>websocket</code> || 每个WebSocket会话创建一个Bean实例(仅适用于WebSocket应用)。 |} === singleton作用域 === '''singleton'''是默认的作用域。在该作用域下,Spring IoC容器仅创建一个Bean实例,并在所有需要该Bean的地方共享它。 <syntaxhighlight lang="xml"> <!-- XML配置方式 --> <bean id="exampleBean" class="com.example.ExampleBean" scope="singleton"/> </syntaxhighlight> <syntaxhighlight lang="java"> // 注解配置方式 @Component @Scope("singleton") public class ExampleBean { ... } </syntaxhighlight> ==== 示例 ==== <syntaxhighlight lang="java"> public class SingletonDemo { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); ExampleBean bean1 = context.getBean("exampleBean", ExampleBean.class); ExampleBean bean2 = context.getBean("exampleBean", ExampleBean.class); System.out.println(bean1 == bean2); // 输出:true } } </syntaxhighlight> === prototype作用域 === '''prototype'''作用域表示每次请求Bean时都会创建一个新的实例。 <syntaxhighlight lang="xml"> <bean id="exampleBean" class="com.example.ExampleBean" scope="prototype"/> </syntaxhighlight> <syntaxhighlight lang="java"> @Component @Scope("prototype") public class ExampleBean { ... } </syntaxhighlight> ==== 示例 ==== <syntaxhighlight lang="java"> public class PrototypeDemo { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); ExampleBean bean1 = context.getBean("exampleBean", ExampleBean.class); ExampleBean bean2 = context.getBean("exampleBean", ExampleBean.class); System.out.println(bean1 == bean2); // 输出:false } } </syntaxhighlight> == Web相关作用域 == 对于Web应用程序,Spring提供了额外的特殊作用域。 === request作用域 === 每个HTTP请求都会创建一个新的Bean实例。 <syntaxhighlight lang="java"> @Component @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS) public class RequestScopedBean { ... } </syntaxhighlight> === session作用域 === 每个用户会话期间共享一个Bean实例。 <syntaxhighlight lang="java"> @Component @Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS) public class SessionScopedBean { ... } </syntaxhighlight> == 作用域选择指南 == 选择适当的作用域需要考虑以下因素: * '''性能''':singleton作用域性能最佳,因为只需创建一次 * '''状态管理''':有状态的Bean通常需要prototype或Web作用域 * '''线程安全''':singleton Bean需要设计为线程安全的 <mermaid> graph TD A[选择Bean作用域] --> B{需要共享状态吗?} B -->|是| C{需要跨请求吗?} B -->|否| D[prototype] C -->|是| E{需要跨会话吗?} C -->|否| F[request] E -->|是| G[session] E -->|否| H[application] </mermaid> == 自定义作用域 == Spring允许注册自定义作用域。实现<code>org.springframework.beans.factory.config.Scope</code>接口并注册到容器中: <syntaxhighlight lang="java"> public class CustomScope implements Scope { // 实现必要方法 } // 注册自定义作用域 ConfigurableBeanFactory factory = context.getBeanFactory(); factory.registerScope("custom", new CustomScope()); </syntaxhighlight> == 实际应用案例 == === 购物车实现 === 电子商务应用中,购物车通常使用session作用域: <syntaxhighlight lang="java"> @Component @Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS) public class ShoppingCart { private List<Product> items = new ArrayList<>(); public void addItem(Product product) { items.add(product); } public List<Product> getItems() { return Collections.unmodifiableList(items); } } </syntaxhighlight> === 配置管理 === 应用配置通常使用singleton作用域: <syntaxhighlight lang="java"> @Component public class AppConfig { @Value("${app.timeout}") private int timeout; // 配置getter方法 } </syntaxhighlight> == 数学表示 == 在singleton作用域中,Bean实例可以表示为: <math> \forall b \in B, \exists! i \in I : b \mapsto i </math> 其中: * <math>B</math>是Bean定义的集合 * <math>I</math>是实例的集合 而在prototype作用域中: <math> \forall b \in B, \forall r \in R, \exists i \in I : (b, r) \mapsto i </math> 其中<math>R</math>表示请求的集合。 == 常见问题 == === 作用域代理 === 当注入较短生命周期作用域(如prototype)到较长生命周期Bean(如singleton)时,需要使用代理: <syntaxhighlight lang="java"> @Component public class SingletonBean { @Autowired private Provider<PrototypeBean> prototypeBeanProvider; public void usePrototype() { PrototypeBean prototype = prototypeBeanProvider.get(); // 使用prototype实例 } } </syntaxhighlight> === 线程安全问题 === singleton作用域的Bean需要特别注意线程安全: <syntaxhighlight lang="java"> @Component public class CounterService { private final AtomicInteger counter = new AtomicInteger(0); public int incrementAndGet() { return counter.incrementAndGet(); } } </syntaxhighlight> == 总结 == Spring Bean作用域是框架中一个基础但强大的概念,它决定了Bean实例的生命周期和共享方式。合理选择作用域可以: * 优化应用性能 * 简化状态管理 * 提高代码的可维护性 理解并正确应用各种作用域,是成为高效Spring开发者的重要一步。 [[Category:后端框架]] [[Category:Spring]] [[Category:Spring Ioc容器]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)