1.Bean的类型
1.1 普通Bean
@Component
public class Child {
}
@Bean
public Child child() {
return new Child();
}
<bean class="com.linkedbear.spring.bean.a_type.bean.Child"/>
1.2 FactoryBean
顾名思义是用工厂方法创建Bean
FactoryBean 本身是一个接口,它本身就是一个创建对象的工厂。如果 Bean 实现了 FactoryBean 接口,则它本身将不再是一个普通的 Bean ,不会在实际的业务逻辑中起作用,而是由创建的对象来起作用。
FactoryBean 接口有三个方法:
public interface FactoryBean<T> {
// 返回创建的对象
@Nullable
T getObject() throws Exception;
// 返回创建的对象的类型(即泛型类型)
@Nullable
Class<?> getObjectType();
// 创建的对象是单实例Bean还是原型Bean,默认单实例
default boolean isSingleton() {
return true;
}
}
2.Bean的作用域
2.1SpringFramework中内置的作用域
SpringFramework 中内置了 6 种作用域(5.x 版本):
作用域类型 | 概述 |
---|---|
singleton | 一个 IOC 容器中只有一个【默认值】 |
prototype | 每次获取创建一个 |
request | 一次请求创建一个(仅Web应用可用) |
session | 一个会话创建一个(仅Web应用可用) |
application | 一个 Web 应用创建一个(仅Web应用可用) |
websocket | 一个 WebSocket 会话创建一个(仅Web应用可用) |
2.2 singleton:单实例Bean
SpringFramework 官方文档中有一张图,解释了单实例 Bean 的概念:
左边的几个定义的 Bean 同时引用了右边的同一个 accountDao ,对于这个 accountDao 就是单实例 Bean 。
SpringFramework 中默认所有的 Bean 都是单实例的,即:一个 IOC 容器中只有一个。下面咱演示一下单实例 Bean 的效果:
2.3 prototype 原型Bean
Spring 官方的定义是:每次对原型 Bean 提出请求时,都会创建一个新的 Bean 实例。这里面提到的 ”提出请求“ ,包括任何依赖查找、依赖注入的动作,都算做一次 ”提出请求“ 。由此咱也可以总结一点:如果连续 getBean() 两次,那就应该创建两个不同的 Bean 实例;向两个不同的 Bean 中注入两次,也应该注入两个不同的 Bean 实例。SpringFramework 的官方文档中也给出了一张解释原型 Bean 的图:
其实对于原型这个概念,在设计模式中也是有对应的:原型模式。原型模式实质上是使用对象深克隆,乍看上去跟 SpringFramework 的原型 Bean 没什么区别,但咱仔细想,每一次生成的原型 Bean 本质上都还是一样的,只是可能带一些特殊的状态等等,这个可能理解起来比较抽象,可以跟下面的 request 域结合着理解。
2.3.1 修改Bean的类型
给 Toy 的类上标注一个额外的注解:@Scope ,并声明为原型类型:
@Component
@Scope("prototype")
public class Toy {
}
注意,这个 prototype 不是随便写的常量,而是在 ConfigurableBeanFactory 中定义好的常量:
public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry {
String SCOPE_SINGLETON = "singleton";
String SCOPE_PROTOTYPE = "prototype";
2.4 web应用的作用域
上面表中还涉及到几个关于 Web 应用的作用域,它们都是在 Web 应用中才会有的,这个咱放到后面介绍 SpringWebMvc 时再介绍,这里只是简单介绍一下。
- request :请求Bean,每次客户端向 Web 应用服务器发起一次请求,Web 服务器接收到请求后,由 SpringFramework 生成一个 Bean ,直到请求结束
- session :会话Bean,每个客户端在与 Web 应用服务器发起会话后,SpringFramework 会为之生成一个 Bean ,直到会话过期
- application :应用Bean,每个 Web 应用在启动时,SpringFramework 会生成一个 Bean ,直到应用停止(有的也叫 global-session )
- websocket :WebSocket Bean ,每个客户端在与 Web 应用服务器建立 WebSocket 长连接时,SpringFramework 会为之生成一个 Bean ,直到断开连接
上面 3 种可能小伙伴们还熟悉,最后一种 WebSocket 可能有些小伙伴还不了解,不了解没关系,这玩意用的也少,等回头小伙伴学习了 WebSocket 之后自己试一下就可以了,小册这里也不多展开了。
3.Bean实例化的方式
3.1普通Bean实例化
其实咱前面创建的所有
3.2 FactoryBean创建Bean
3.3 使用静态工厂创建Bean
3.4 借助实例工厂创建Bean
注:【面试题】BeanFactory与FactoryBean的区别
以下答案仅供参考,可根据自己的理解调整回答内容:
BeanFactory :SpringFramework 中实现 IOC 的最底层容器(此处的回答可以从两种角度出发:从类的继承结构上看,它是最顶级的接口,也就是最顶层的容器实现;从类的组合结构上看,它则是最深层次的容器,ApplicationContext 在最底层组合了 BeanFactory )
FactoryBean :创建对象的工厂 Bean ,可以使用它来直接创建一些初始化流程比较复杂的对象