Spring Bean范围

介绍:

Spring核心容器实例化bean并管理其生命周期 在定义bean时,我们可以提供其范围。 除非明确提供,否则单例是Spring容器中bean的默认范围。

Spring提供了五种类型的bean作用域。 在本教程中,我们将探讨它们中的每一个。

1.

单例作用域可确保每个Spring IoC容器仅存在该bean的一个实例。 该单个Bean实例存储在所有单个Bean的缓存中,并为每个后续请求返回对此缓存对象的引用。

众所周知,默认情况下,所有Spring bean都是单例的。

假设我们有一个Student bean:

@Component
public class Student {
 
    private int id;
    private String name;
 
    //constructor, getters, setters
 
}

默认情况下, Student类将是单例bean。 让我们尝试将其加载到我们的main()方法中:

public class App {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("appContext.xml");
        Student student1 = (Student) context.getBean("student");
 
        student1.setName("John");
        System.out.println(student1.getName()); //Prints 'John'
 
        Student student2 = (Student) context.getBean("student");
        System.out.println(student2.getName()); //Prints 'John'
   }
}

显然,已经为第二次调用返回了Student Bean的现有实例。 换句话说, student1student2引用都指向同一对象。

2.

对于原型范围内的bean,在我们的应用程序代码中为该特定bean的每个请求创建一个新实例

我们可以使用@Scope批注将bean的范围配置为原型

@Component
@Scope("prototype")
public class Student {
 
    ...
}

或使用基于XML的配置时,我们将:

<bean id = "student" class="org.programmergirl.domain.Student"
  scope="prototype">
</bean>

现在,让我们看看在main()方法中会发生什么:

public class App {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("appContext.xml");
        Student student1 = (Student) context.getBean("student");
 
        student1.setName("John");
        System.out.println(student1.getName()); //Prints 'John'
 
        Student student2 = (Student) context.getBean("student");
        System.out.println(student2.getName()); //Prints null
   }
}

这里, student2引用Student类的新实例,其名称属性为null

注意,我们应该始终对有状态bean使用原型作用域,对无状态bean使用单例作用域。

3.

使用请求范围时,将为每个HTTP请求创建一个新实例。 HTTP请求完成时,该bean实例将被销毁。

我们可以使用注释配置请求范围:

@Component
@Scope("request")
public class Student {
   ...
}
 
//Or
 
@Component
@RequestScope
public class Student {
   ...
}

或通过XML配置:

<bean id = "student" class="org.programmergirl.domain.Student"
  scope="request">
</bean>

4.

对于会话范围,Spring容器为每个HTTP会话创建一个新的bean实例。 HTTP会话中的所有HTTP请求将共享相同的bean实例。

要配置会话范围的Bean,我们将使用:

@Component
@Scope("session")
public class Student {
   ...
}
 
//Or
 
@Component
@SessionScope
public class Student {
   ...
}

对于基于xml的配置,我们将有:

<bean id = "student" class="org.programmergirl.domain.Student"
  scope="session">
</bean>

当HTTP会话关闭时,容器将销毁会话范围的Bean实例。

5.

应用程序范围内,可感知Web的容器会根据ServletContext创建一个bean实例。 请注意,应用程序范围不同于单例范围:

  • 我们可以在独立应用程序中使用单例作用域。 该应用程序范围仅对基于Web的Spring容器/应用程序有效
  • 对于单例作用域,每个应用程序上下文存在一个实例。 另一方面,应用程序范围的Bean对于整个ServletContext具有单个实例。 我们可能有多个应用程序共享同一个ServletContext

让我们将Student bean配置为应用程序范围的bean:

@Component
@Scope("application")
public class Student {
   ...
}
 
//Or
 
@Component
@ApplicationScope
public class Student {
   ...
}

基于xml的定义如下所示:

<bean id = "student" class="org.programmergirl.domain.Student"
  scope="application"> 
</bean>

结论:

在本教程中,我们探索了各种Spring bean范围。

请注意,请求,会话应用程序bean范围仅对可感知网络的Spring ApplicationContext有效

翻译自: https://www.javacodegeeks.com/2019/06/spring-bean-scopes.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值