Spring学习(五)-Bean的作用域

本文详细介绍了Spring框架中Bean的不同作用域,包括单例、原型、会话和请求作用域的特点及应用场景,并提供了具体的示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一篇博客,介绍了利用@Qualifier消除同种类型Bean之间的歧义性,本篇博客给出JavaBean装配另一高级特性-bean的作用域。

在默认情况下,Spring中应用上下文中所有Bean都是作为单例的形式创建的。换计划说,不管给定的一个bean被注入到其他Bean中多少次,每次注入的都是同一个实例。例如:

定义一个Dog

package com.wygu.spring.animal;

public class Dog implements Animal{

    private int index;
    private String dogName;

    public Dog(String dogName,int index) {
        this.dogName = dogName;
        this.index = index;
    }

    @Override
    public void walk() {
        System.out.println("The Dog name: "+dogName+" is walking"+";index:"+index++);   
    }

}

在AnimalFactory中同一个bean(id为“dog”)被注入两次

package com.wygu.spring.animal;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public class AnimalFactory {


    private Animal animal1;

    private Animal animal2;

    public Animal getAnimal1() {
        return animal1;
    }

    @Autowired
    @Qualifier("dog")
    public void setAnimal1(Animal animal1) {
        this.animal1 = animal1;
    }

    public Animal getAnimal2() {
        return animal2;
    }

    @Autowired
    @Qualifier("dog")
    public void setAnimal2(Animal animal2) {
        this.animal2 = animal2;
    }

}

对应xml配置文件为:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.3.xsd">

   <context:annotation-config/>

    <bean id="factory1" class="com.wygu.spring.animal.AnimalFactory"/> 

    <!-- 通过构造器参数索引进行注入 --> 
    <bean id="dog" class="com.wygu.spring.animal.Dog">
        <constructor-arg index="0" value="欧巴"/>  
        <constructor-arg index="1" value="1"/>  
    </bean>

</beans>

执行结果为:
The Dog name: 欧巴 is walking;index:1
The Dog name: 欧巴 is walking;index:2
显然bean虽然被注入了两次,但是都是相同的实例。有时候,使用的类是易变的,他们会保持一些状态,因此如果还保持单例是不合适的。

在Spring中定义了多种作用域,我们构造Bean时可以基于这些作用域,主要包括:

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

原型作用域(Prototype)

对于上述示例,我们只需要在XML配置中加入:

<bean id="dog" class="com.wygu.spring.animal.Dog" scope="prototype">
        <constructor-arg index="0" value="欧巴"/>  
        <constructor-arg index="1" value="1"/>  
    </bean>

运行程序,输出为:
The Dog name: 欧巴 is walking;index:1
The Dog name: 欧巴 is walking;index:1

会话作用域(Session)&请求作用域(Request)

在电子商务应用中,需要一个bean对应一个购物车。因为如果购物车是单例模式的话,会导致所有用户共享同一个购物车,如果购物车是原型模式的话,会导致在一个页面中可以添加到该购物车,另一个页面无法正常添加的问题。我们引入会话作用域,可以很完美的解决这个问题。

@Component
@Scope(value=WebApplicationContext.SCOPE_SESSION)
public class CatShoppingCart implements ShoppingCart{
    public ShoppingCart getCatShoppingCart(){
        return new CatShoppingCart ();
    }
}

我们将scope的value设置为WebApplicationContext中的SCOPE_SESSION常量,表明为Web应用中的每个会话创建一个ShoppingCart。对于每个给定的会话,只会创建一个实例。

如果我们在scope作用域中加入代理模式:

@Scope(value=WebApplicationContext.SCOPE_SESSION,proxyMode=ScopedProxyMode.INTERFACES)

proxyMode=ScopedProxyMode.INTERFACES主要可以解决将会话或请求作用域的bean注入到单例bean中所遇到的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值