持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第14天,点击查看活动详情
Bean 的介绍
Spring Bean
是 Spring IOC
容器在运行时管理的对象。Spring Bean
是 Spring
程序中不可或缺的一部分。如果将 Spring
看做一个大型工厂的话,那么 Bean
就是这个工厂中的产品。如果要想让这个工厂来生产和管理 Bean
,就需要在配置文件中告诉它需要哪些 Bean
,以及如何组装这些 Bean
。这里所说的 Bean
本质就是 Java 中的类。
下面是配置文件中一个 bean
标签中所涉及到的属性,如下表所示 :
属性 | 描述 |
---|---|
class | 这个属性是强制性的,并且指定用来创建 bean 的 bean 类。 |
id | 这个属性指定唯一的 bean 标识符。在基于 XML 的配置元数据中,你可以使用 id 或 name 属性来指定 bean 标识符。 |
scope | 这个属性指定由特定的 bean 定义创建的对象的作用域。 |
constructor-arg | 它是用来注入依赖关系的 |
properties | 它是用来注入依赖关系的 |
autowiring mode | 它是用来注入依赖关系的 |
lazy-initialization mode | 延迟初始化的 bean 告诉 IoC 容器在它第一次被请求时,而不是在启动时去创建一个 bean 实例。 |
initialization 方法 | 在 bean 的所有必需的属性被容器设置之后,调用回调方法。 |
destruction 方法 | 当包含该 bean 的容器被销毁时,使用回调方法。 |
Bean 的作用域
默认情况下,Spring
只会为 IOC
容器中声明的 Bean
创建一个实例,并且这个实例是在整个 IOC
容器范围内都能共享的,所以后续的对象通过 getBean()
方法调用和 Bean
的引用都将返回这个唯一的实例。假如我们现在需要不同的实例 Bean
,我们该如何处理呢?
这就设计到 Bean
的作用域了。还记得前面加粗的属性 scope
吗,它就是用来指定 Bean
的作用域的。默认情况下,scope
的值为 Singleton
,表示单例。在 Spring
中提供了 6 种作用域,如下表所示 :
作用域 | 描述 |
---|---|
singleton | 单例模式(默认) ,实例化的 Bean 在整个 Spring IOC 容器生命周期中只创建一次,单个 Bean 被绑定到单个对象实例。 |
prototype | 多例模式,Spring IOC 容器初始化时不创建 Bean 的实例,而是在通过 getBean 获取 Bean 时才会创建一个新的 Bean 实例并返回, 单个 Bean 定义可以被绑定到多个对象实例。 |
request | 单个 Bean 定义被绑定到单个的 HTTP 请求生命周期。就是每一个 HTTP 请求都有属于他自己的单独实例创建,这个只能在 web-aware Spring ApplicationContext 中有效。 |
session | 单个 Bean 定义会被绑定到 HTTP Session 的生命周期中,这个只能在 web-aware Spring ApplicationContext 中有效。 |
application | 单个 Bean 定义会被绑定到 ServletContext 的生命周期中,这个只能在 WebApplicationContext 中有效。 |
websocket | 单个 Bean 的定义会被绑定到 WebSocket 的生命周期中,这个只能在 WebApplicationContext 中有效。 |
上述几种作用域,在实际开发中 singleton
和 prototype
值最常用的两种。
1. singleton
a. 在 applicationContextByName.xml
配置文件中配置 Employee
这个 JaveBean
,并指定 scope="singleton"
,如下所示
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="employee" class="com.yamiya.pojo.Employee" scope="singleton">
</bean>
</beans>
说明:scope
是用来设置作用域的,如果不写,默认也是 singleton
,表示单例。
b.在测试类 SpringTest
中添加测试方法,代码如下:
@Test
public void test1() throws IOException{
Employee e1 = context.getBean("employee",Employee.class);
Employee e2 = context.getBean("employee",Employee.class);
Employee e3 = context.getBean("employee",Employee.class);
System.out.println(e1);
System.out.println(e2);
System.out.println(e3);
}
分析:观察上图可以发现,虽然调用三次 getBean
方法获取了三个实例对象,但是三个实例对象的地址都是一样的,也就是说这三个实例对象实际是同一个实例对象。这就是单例模式(singleton
),它是在 Bean
整个生命周期内只被创建一次,创建好了之后,它在整个 IOC
容器中是被共享的。
2. prototype
a. 将配置文件中的作用域改为 scope="prototype"
,代码如下
b. 测试代码不变,直接点击进行测试,结果如下图所示
分析:观察上图可以发现,调用三次 getBean
方法获取了三个实例对象,三个实例对象的地址都不一样,也就是说分别创建了三个实例对象。这就是多例模式(prototype
),实例对象是在调用 getBean
方法时才会被创建,每调用一次 getBean
方法获取的实例化对象都不一样。
总结
Spring Bean
作用域,重点是以下两种作用域:
-
singleton
:表示单例(默认)模式实例化的
Bean
在整个Spring IOC
容器生命周期中只创建一次,单个Bean
被绑定到单个对象实例 -
prototype
:表示多例模式Spring IOC
容器初始化时不创建Bean
的实例,而是在通过getBean
获取Bean
时才会创建一个新的Bean
实例并返回, 单个Bean
定义可以被绑定到多个对象实例。