Spring2.x中设置Bean的作用域

简介: 在配置文件里声明的Bean时,实际定义的并不是一个Bean实例,而是为Bean创建了一个模板,当通过getBean()调用或其他请求改Bean的时候,Spring将根据Bean的实际作用域返回Bean的实例,在某些情况下默认的作用域并不适合,此时需要为Bean设置一个更适合的作用域。

 
在配置文件里声明的Bean时,实际定义的并不是一个Bean实例,而是为Bean创建了一个模板,当通过getBean()调用或其他请求改Bean的时候,Spring将根据Bean的实际作用域返回Bean的实例,在某些情况下默认的作用域并不适合,此时需要为Bean设置一个更适合的作用域。

在Spring2.x里,可以通过<bean>中的scope属性设置作用域,默认情况下Spring只为在Ioc容器里声明的Bean创建一个实例,整个Ioc范围内都共享这个实例,所有后续的getBean()调用和引用该实例,都将返回这个唯一的Bean实例。这个作用域称为singleton,是默认的作用域。

Spring2.x中Bean的几种作用域:

1、singleton--------------为每个Spring Ioc容器创建一个Bean实例;

2、prototype-------------每次请求时都创建一个新的实例;

3、request---------------每个HTTP请求创建一个Bean实例,这个作用域仅在WEB应用程序的上下文中有效;

4、session---------------每个HTTP请求创建一个Bean实例,这个作用域仅在WEB应用程序的上下文中有效;

5、globalSession------为每个全局的HTTP会话创建一个Bean实例,这个作用域尽在门户应用程序的上下文中有效;

下边将用一个商品购物车例子来说明这个Bean的实例作用域:

package com.song.spring.scope;

public abstract class Product {

	private String name;
	private double price;
	
	public Product(){}
	
	public Product(String name, double price){
		this.name = name;
		this.price = price;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public double getPrice() {
		return price;
	}

	public void setPrice(double price) {
		this.price = price;
	}
	
	public String toString(){
		return name + " " + price;
	}
}

package com.song.spring.scope;

public class Battery extends Product {

	private boolean rechargeable;
	
	public Battery(){
		super();
	}
	
	public Battery(String name, double price){
		super(name, price);
	}

	public boolean isRechargeable() {
		return rechargeable;
	}

	public void setRechargeable(boolean rechargeable) {
		this.rechargeable = rechargeable;
	}
	
	
}

package com.song.spring.scope;

public class Disc extends Product {

	private int capacity;
	
	public Disc(){
		super();
	}
	
	public Disc(String name, double price){
		super(name, price);
	}

	public int getCapacity() {
		return capacity;
	}

	public void setCapacity(int capacity) {
		this.capacity = capacity;
	}
	
	
}

接下来创建一个无购物车实例;

package com.song.spring.scope;

import java.util.ArrayList;
import java.util.List;

public class ShoppingCart {

	private List<Product> items = new ArrayList<Product>();
	
	public void addItem(Product item){
		items.add(item);
	}
	
	public List<Product> getItem(){
		return items;
	}
}

在classpath:下的xml文件applicationContext.xml中的Bean配置为:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
        "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>    
	<bean id="aaa" class="com.song.spring.scope.Battery">
		<property name="name" value="AAA" />
		<property name="price" value="2.5" />
	</bean>
	
	<bean id="cdrw" class="com.song.spring.scope.Disc">
		<property name="name" value="CD-RW" />
		<property name="price" value="1.5" />
	</bean>
	
	<bean id="dvdrw" class="com.song.spring.scope.Disc">
		<property name="name" value="DVD-RW" />
		<property name="price" value="3.0" />
	</bean>
	
	<bean id="shoppingCart" class="com.song.spring.scope.ShoppingCart" />
</beans>

创建一个运行类:

package com.song.spring.scope;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

	public static void main(String[] args) {

		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		
		Product aaa = (Product)context.getBean("aaa");
		Product cdrw = (Product)context.getBean("cdrw");
		Product dvdrw = (Product)context.getBean("dvdrw");
		
		ShoppingCart cart1 = (ShoppingCart)context.getBean("shoppingCart");
		cart1.addItem(aaa);
		cart1.addItem(cdrw);
		System.out.println("Shopping Cart1 contains:" + cart1.getItem());
		
		ShoppingCart cart2 = (ShoppingCart)context.getBean("shoppingCart");
		cart2.addItem(dvdrw);
		System.out.println("Shopping Cart2 contains:" + cart2.getItem());
	}

}
运行结果为:

Shopping Cart1 contains:[AAA 2.5, CD-RW 1.5]
Shopping Cart2 contains:[AAA 2.5, CD-RW 1.5, DVD-RW 3.0]

显然这不是我们想要的结果;我们所要的是每个顾客各获得一个Bean实例,这时就应该将配置文件中的Bean实例的作用域改为prototype;

<bean id="shoppingCart" class="com.song.spring.scope.ShoppingCart" scope="prototype"/>


再运行所得结果为:

Shopping Cart1 contains:[AAA 2.5, CD-RW 1.5]
Shopping Cart2 contains:[DVD-RW 3.0]

这才是我们想要的结果,完毕!


目录
相关文章
|
10天前
|
XML 安全 Java
|
1月前
|
缓存 Java Spring
实战指南:四种调整 Spring Bean 初始化顺序的方案
本文探讨了如何调整 Spring Boot 中 Bean 的初始化顺序,以满足业务需求。文章通过四种方案进行了详细分析: 1. **方案一 (@Order)**:通过 `@Order` 注解设置 Bean 的初始化顺序,但发现 `@PostConstruct` 会影响顺序。 2. **方案二 (SmartInitializingSingleton)**:在所有单例 Bean 初始化后执行额外的初始化工作,但无法精确控制特定 Bean 的顺序。 3. **方案三 (@DependsOn)**:通过 `@DependsOn` 注解指定 Bean 之间的依赖关系,成功实现顺序控制,但耦合性较高。
实战指南:四种调整 Spring Bean 初始化顺序的方案
|
8天前
|
安全 Java 开发者
Spring容器中的bean是线程安全的吗?
Spring容器中的bean默认为单例模式,多线程环境下若操作共享成员变量,易引发线程安全问题。Spring未对单例bean做线程安全处理,需开发者自行解决。通常,Spring bean(如Controller、Service、Dao)无状态变化,故多为线程安全。若涉及线程安全问题,可通过编码或设置bean作用域为prototype解决。
17 1
|
2月前
|
XML Java 数据格式
Spring从入门到入土(bean的一些子标签及注解的使用)
本文详细介绍了Spring框架中Bean的创建和使用,包括使用XML配置文件中的标签和注解来创建和管理Bean,以及如何通过构造器、Setter方法和属性注入来配置Bean。
75 9
Spring从入门到入土(bean的一些子标签及注解的使用)
|
2月前
|
Java 测试技术 Windows
咦!Spring容器里为什么没有我需要的Bean?
【10月更文挑战第11天】项目经理给小菜分配了一个紧急需求,小菜迅速搭建了一个SpringBoot项目并完成了开发。然而,启动测试时发现接口404,原因是控制器包不在默认扫描路径下。通过配置`@ComponentScan`的`basePackages`字段,解决了问题。总结:`@SpringBootApplication`默认只扫描当前包下的组件,需要扫描其他包时需配置`@ComponentScan`。
|
3月前
|
XML Java 数据格式
spring复习02,xml配置管理bean
详细讲解了Spring框架中基于XML配置文件管理bean的各种方式,包括获取bean、依赖注入、特殊值处理、属性赋值、集合类型处理、p命名空间、bean作用域及生命周期和自动装配。
spring复习02,xml配置管理bean
|
2月前
|
存储 Java API
简单两步,Spring Boot 写死的定时任务也能动态设置:技术干货分享
【10月更文挑战第4天】在Spring Boot开发中,定时任务通常通过@Scheduled注解来实现,这种方式简单直接,但存在一个显著的限制:任务的执行时间或频率在编译时就已经确定,无法在运行时动态调整。然而,在实际工作中,我们往往需要根据业务需求或外部条件的变化来动态调整定时任务的执行计划。本文将分享一个简单两步的解决方案,让你的Spring Boot应用中的定时任务也能动态设置,从而满足更灵活的业务需求。
134 4
|
2月前
|
Java 开发者 Spring
Spring bean的生命周期详解!
本文详细解析Spring Bean的生命周期及其核心概念,并深入源码分析。Spring Bean是Spring框架的核心,由容器管理其生命周期。从实例化到销毁,共经历十个阶段,包括属性赋值、接口回调、初始化及销毁等。通过剖析`BeanFactory`、`ApplicationContext`等关键接口与类,帮助你深入了解Spring Bean的管理机制。希望本文能助你更好地掌握Spring Bean生命周期。
120 1
|
2月前
|
Java Spring
获取spring工厂中bean对象的两种方式
获取spring工厂中bean对象的两种方式
46 1
|
2月前
|
Java 开发者 Spring
Spring bean的生命周期详解!
本文详细介绍了Spring框架中的核心概念——Spring Bean的生命周期,包括实例化、属性赋值、接口回调、初始化、使用及销毁等10个阶段,并深入剖析了相关源码,如`BeanFactory`、`DefaultListableBeanFactory`和`BeanPostProcessor`等关键类与接口。通过理解这些核心组件,读者可以更好地掌握Spring Bean的管理和控制机制。
95 1