Spring中Bean的作用域介绍

    技术2025-09-06  51

    Spring中Bean的作用域详解

    Bean简介Bean作用域Singleton介绍Prototype介绍Request介绍Session介绍

    Bean简介

    在Spring中,组成应用程序的主体、由SpringIoC容器所管理的对象,被称之为bean。简单来讲,也就是由IoC容器进行初始化、装配、管理(生命周期和依赖关系)的对象。

    Bean作用域

    其中request、session的作用域仅在基于web的SpringContext环境中使用。

    Singleton介绍

    Spring缺省作用域,Singleton是单例类型,默认在创建容器时就自动创建了一个bean的对象,这样不管是否使用,都已经存在,并且每次获取到的是同一对象。 当一个bean的作用域为Singleton,那么SpringIoC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。

    XML中将一个bean定义为Singleton:

    <bean id="user" class="com.ahy.pojo.User" scope="singleton"> </bean>

    测试:

    @Test void test01() { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicaitonContext.xml"); User user1 =(User) context.getBean("user"); User user2 =(User) context.getBean("user"); System.out.println(user1 == user2);//true }

    配置类中声明bean为Singleton:

    @Configuration public class SpringConfiguration { @Bean @Scope("singleton") public People people(){ return new People("jack",55); } public class People{ private String name; private int age; public People(String name, int age) { this.name = name; this.age = age; } } }

    测试:

    @Test public void test01(){ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfiguration.class); User.People people1 =(User.People) context.getBean("people"); User.People people2 =(User.People) context.getBean("people"); System.out.println(people1 == people2 );//true }

    设置bean为懒加载,也就是在调用容器的getBean()方法时再加载:

    <bean id="people" class="com.ahy.pojo.User.People" lazy-init="true"></bean>

    Prototype介绍

    Prototype是原型类型,在我们创建容器的时候并没有实例化,而是当我们获取bean的时候才会去创建一个对象,并且我们每次获取到的对象都不是同一个对象。 当一个bean的作用域为Prototype,表示一个bean定义对应多个对象实例。Prototype作用域的bean会导致在每次对该bean请求时(将其注入到另一个bean中,或者调用容器的getBean()方法),都会创建一个新的bean实例。

    根据经验,对有状态的bean应该使用Prototype作用域,而对无状态的bean应该使用Singleton作用域。

    XML中将bean定义为Prototype:

    <bean id="people" class="com.ahy.pojo.User.People" scope="prototype"></bean>

    或者:

    <bean id="people" class="com.ahy.pojo.User.People" singleton="false"></bean>

    测试:

    @Test public void test01(){ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); User user1 =(User) context.getBean("user"); User user2 =(User) context.getBean("user"); System.out.println(user1 == user2);//false }

    配置类中声明bean为Prototype:

    @Configuration public class SpringConfiguration { @Bean @Scope("prototype") public People people(){ return new People("jack",55); } public class People{ private String name; private int age; public People(String name, int age) { this.name = name; this.age = age; } } }

    测试:

    @Test public void test01(){ // ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(User.class); User.People user1 =(User.People) context.getBean("people"); User.People user2 =(User.People) context.getBean("people"); System.out.println(user1 == user2);//false }

    Request介绍

    当一个bean作用域为Request,表示在一次HTTP请求中,一个bean对应一个实例;即每个HTTP请求都会有各自的bean实例。该作用域仅在基于web的SpringApplicaitonContext情形下有效。

    XML中将bean定义为Request:

    <bean id="loginAction" class="com.ahy.LoginAction" scope="request"></bean>

    针对每次HTTP请求。Spring容器会根据loginAction bean的定义创建一个全新的LoginAction bean实例,且该实例仅在当前HTTP request请求内有效,因此可以根据需要放心的更改该实例的内部状态,而其他请求中根据loginAction bean定义创建的实例,将不会看到这些特定于某个请求的状态变化。当处理请求结束,request作用域的bean实例将被销毁。

    Session介绍

    当一个bean的作用域为Session,表示在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。 XML中将bean定义为Session:

    <bean id="userPreferences" class="com.ahy.UserPreferences" scope="session"/>

    针对某个HTTP Session,Spring容器会根据userPreferences bean定义创建一个全新的userPreferences bean实例,且该userPreferences bean仅在当前HTTP Session内有效。与request作用域一样,可以根据需要放心的更改所创建实例的内部状态,而别的HTTP Session中根据userPreferences创建的实例,将不会看到这些特定于某个HTTP Session的状态变化。当HTTP Session最终被废弃的时候,在该HTTP Session作用域内的bean也会被废弃掉。

    Processed: 0.011, SQL: 9