Spring的Bean作用域 --《Spring In Action》

在默认情况下,Spring App上下文中所有Bean都是单例(singleton)的形式创建。不管给定的一个bean被注入多少次,每次所注入的都是同一个实例。

Bean 作用域

  • 单例(Singleton):在整个应用中,只创建bean的一个实例(默认作用域)
  • 原型(Prototype):每次注入或者通过Spring App上下文获取的时候都会创建新的bean实例
  • 会话(Session):在Web应用中,为每个会话创建一个Bean实例
  • 请求(Request):在Web应用中,为每个请求创建一个Bean实例

如何指定Bean的作用域

  • 第一种方式在通过@Scope注解
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public Notepad notepad(){
return new Notepad();
}
  • 第二种方式在XML配置作用域
<bean id="notepad" class="com.myapp.Notepad" scope="prototype"/>

使用会话和请求作用域

在Web应用中,如电子商务应用中的购物车Bean如果是单例的话会导致所有用户都会向一个购物车中添加商品。另一个方面如果购物车是原型作用域在应用中其他的地方不会出现造成资源浪费。

@Component
@Scope(value=WebApplicationContext.SCOPE_SESSION, proxyMode=ScopedProxyMode.INTERFACES)
public ShoppingCart cart(){...}
// value=WebApplicationContext.SCOPE_SESSION : 表明Spring为Web应用中的每个会话创建一个ShoppingCart
// proxyMode=ScopedProxyMode.INTERFACES : 表明解决了将会话或请求作用域的bean注入到单例Bean中所遇到的问题

proxyMode=ScopedProxyMode.INTERFACES;表明这个代理要实现ShoppingCart接口,并将调用委托给实现bean。如果Bean的类型就是具体类而不是接口则需要改变属性值proxyMode=ScopedProxyMode.TARGET_CLASS来表明要以生成目标类扩展的方式创建代理。

作用域代理能够延迟注入请求和会话作用域的Bean

  • 在XML中配置作用域
<bean id="cart" class="com.myapp.ShoppingCart" scope="session">
<aop:aspect-proxy proxy-target-class="false"/>
</bean>

实现运行时注入

  • 传统“硬编码”注入方式
//- Java中
@Bean
public CompactDisc sgtPeppers(){
return new BlankDisc("Sgt, Pepper's Lonely", "The Beatles");
}
// - XML中
<bean id="sgtPeppers"
class="soundsystem.BlankDisc"
c:_title="xxx"
c:_artist="xxx"/>

Spring提供两种运行时注入值的方式

注入外部值

@Configuration
@PropertySource("classpath:/com/soundsystem/app.properties") // 声明属性源
public class BlankDisc{
@Autowired
Environment env;
@Bean
public BlankDisc disc(){
return new BlankDisc(env.getProperty("disc.title"),env.getProperty("disc.artist")); // 检索属性值
}
}
/**app.properties
disc.title="xxx"
disc.artist="xxx"
*/

Spring的Environment中存在四种getProperty()重载的变种形式

  1. String getProperty(String key)
  2. String getProperty(String key, String defaultValue)
  3. T getProperty(String key, Class type)
  4. T getProperty(String key, Class type, T defaultValue)

属性占位符(Property placeholder)

// XML 设置
<bean id="sgtPeppers" class="soundsystem.BlankDisc" c:_title="${disc.title}" c:_artist="${disc.artist}"/>
// Java 设置
public BlankDisc{@Value("${disc.title}") String title, @Value("${disc.artist}") String artist){
this.title = title;
this.artist = artist;
}
// 在web.xml中开启SpEL
<context:property-placeholder/>
posted @   Felix_Openmind  阅读(138)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
*{cursor: url(https://files-cdn.cnblogs.com/files/morango/fish-cursor.ico),auto;}
点击右上角即可分享
微信分享提示