文章目录
整体概述
FactoryBean 与 BeanFactory 区别
两者都是用作创建对象
- 使用
BeanFactory
的时候必须要遵循完整的创建过程,这个过程由spring来管理控制 - 使用
FactoryBean
只需要调用getObject()
就可以返回具体的对象,整个对象的创建过程是由用户自己来控制,更加灵活
FactoryBean 类方法
拓展实践
1. 创建 User 对象
public class User {
private String username;
public User() {
}
public User(String username) {
this.username = username;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
'}';
}
}
2. 创建 FactoryBean 实现类 MyFactoryBean
public class MyFactoryBean implements FactoryBean<User> {
@Override
public User getObject() throws Exception {
//任何创建对象的操作
return new User("zhangsan");
}
@Override
public Class<?> getObjectType() {
return User.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
3. 新建配置文件 factoryBean.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="myFactoryBean" class="com.mashibing.MyFactoryBean">
</bean>
</beans>
4. 测试类
public class Test {
public static void main(String[] args) {
MyClassPathXmlApplicationContext ac = new MyClassPathXmlApplicationContext("factoryBean.xml");
MyFactoryBean bean1 = (MyFactoryBean) ac.getBean( "&myFactoryBean");
System.out.println(bean1);
User bean = (User) ac.getBean("myFactoryBean");
System.out.println(bean.getUsername());
User bean2 = (User) ac.getBean("myFactoryBean");
System.out.println(bean2.getUsername());
}
}
概要解析
实现 FactoryBean 的类包含了几个对象
- 实现 FactoryBean 接口的对象,即 MyFactoryBean
- 通过 getObject() 方法返回的对象,即 User
两个对象都由 Spring 管理,其中 MyFactoryBean 存放在一级缓存 singletonObjects 中,User 存放在 factoryBeanObjectCache 中
MyFactoryBean bean1 = (MyFactoryBean) ac.getBean( “&myFactoryBean”) 执行流程
(1)String beanName = transformedBeanName(name);
在doGetBean() 中 先取得去掉 name 中前缀 “&” 的 beanName
(2)Object sharedInstance = getSingleton(beanName);
然后通过 getSingleton(beanName) 从一级缓存中得到 MyFactoryBean 对象
(3)调用 getObjectForBeanInstance(sharedInstance, name, beanName, null)
从 beanInstannce 中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是FactoryBean会直接返回beanInstance实例
(4)BeanFactoryUtils.isFactoryDereference(name)
判断name是否以“&”为前缀
(5)name 以“&”为前缀直接返回入参中的 MyFactoryBean 对象
User bean = (User) ac.getBean(“myFactoryBean”) 执行流程
与上述1-4步逻辑相同
(5)getObjectFromFactoryBean(factory, beanName, !synthetic);
获取一个对象以从给定的FactoryBean中公开
(6)doGetObjectFromFactoryBean(factory, beanName);
获取factory管理的对象实例
(7)factory.getObject();
调用子类的具体实现
整体脉络
关键源码
getObjectForBeanInstance()
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
// 如果Bean不是工厂,不要让调用代码尝试取消对工厂的引用
// 如果name为FactoryBean的解引用.name是以'&'开头,就是FactoryBean的解引用
if (BeanFactoryUtils.isFactoryDereference(name)) {
// 如果beanInstance是NullBean实例
if (beanInstance instanceof NullBean) {
// 返回beanInstance
return beanInstance;
}
// 如果beanInstance不是FactoryBean实例
if (!(beanInstance instanceof FactoryBean)) {
// 抛出Bean不是一个Factory异常
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
// 如果mbd不为null
if (mbd != null) {
// 设置mbd是否是FactoryBean标记为true
mbd.isFactoryBean = true;
}
// 返回beanInstance
return beanInstance;
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
// 现在我们有了Bean实例,他可能是一个普通的Bean或FactoryBean。
// 如果它是FactoryBean,我们使用它来创建一个Bean实例,除非调用者确实需要对工厂的引用。
// 如果beanInstance不是FactoryBean实例
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
// 定义为bean公开的对象,初始化为null
Object object = null;
// 如果mbd不为null
if (mbd != null) {
// 更新mbd的是否是FactoryBean标记为true
mbd.isFactoryBean = true;
}
else {
// 从FactoryBean获得的对象缓存集中获取beanName对应的Bean对象
object = getCachedObjectForFactoryBean(beanName);
}
// 如果object为null
if (object == null) {
// Return bean instance from factory.
// 从工厂返回Bean实例
// 将beanInstance强转为FactoryBean对象
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
// 如果是单例对象,则缓存从FactoryBean获得的对象、
// 如果mbd为null&&该BeanFactory包含beanName的BeanDefinition对象。
if (mbd == null && containsBeanDefinition(beanName)) {
//获取beanName合并后的本地RootBeanDefintiond对象
mbd = getMergedLocalBeanDefinition(beanName);
}
// 是否是'synthetic'标记:mbd不为null && 返回此bean定义是否是"synthetic"【一般是指只有AOP相关的prointCut配置或者
// Advice配置才会将 synthetic设置为true】
boolean synthetic = (mbd != null && mbd.isSynthetic());
// 从BeanFactory对象中获取管理的对象.如果不是synthetic会对其对象进行该工厂的后置处理
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
// 返回为bean公开的对象
return object;
}
getObjectFromFactoryBean()
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
// 如果factory管理的对象是单例且beanName已经在该BeanFactory的单例对象的高速缓存Map集合DefaultListableBeanFactory.singletonObjects中
if (factory.isSingleton() && containsSingleton(beanName)) {
// 获取单例互斥体(一般使用singletonObjects)进行加锁,来保证线程安全
synchronized (getSingletonMutex()) {
// 获取beanName的Bean对象
Object object = this.factoryBeanObjectCache.get(beanName);
// 如果object为null
if (object == null) {
// 获取factory管理的对象实例并赋值给object
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
// 仅在上面的getObject()调用期间进行后处理和存储(如果尚未放置)
// (例如,由于自定义getBean调用触发的循环引用处理)
// 重新从factoryBeanObjectCache中获取beanName对应bean对象
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
// 如果bean对象不为null
if (alreadyThere != null) {
// 让object引用alreadyThere
object = alreadyThere;
}
else {
// 如果要进行后处理
if (shouldPostProcess) {
// 如果beanName当前正在创建(在整个工厂内)
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
// 暂时返回未处理的对象,尚未存储
// 直接返回object
return object;
}
// 创建单例之前的回调
beforeSingletonCreation(beanName);
try {
// 对从FactoryBean获得的给定对象进行后处理.
object = postProcessObjectFromFactoryBean(object, beanName);
}
// 捕捉所有在进行后处理的抛出的异常
catch (Throwable ex) {
// 抛出Bean创建异常:FactoryBean的单例对象的后处理失败
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
// 创建单例后的回调
afterSingletonCreation(beanName);
}
}
// beanName已经在该BeanFactory的单例对象的高速缓存Map集合DefaultListableBeanFactory.singletonObjects中
if (containsSingleton(beanName)) {
// 将beanName以及object添加到factoryBeanObjectCache中
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
// 返回factory管理的对象实例(该对象已经过工厂的后处理)
return object;
}
}
else {
// 获取factory管理的对象实例
Object object = doGetObjectFromFactoryBean(factory, beanName);
// 如果要进行后处理
if (shouldPostProcess) {
try {
// 对从FactoryBean获得的给定对象进行后处理
object = postProcessObjectFromFactoryBean(object, beanName);
}
// 捕捉所有在进行后处理的抛出的异常
catch (Throwable ex) {
// 抛出Bean创建异常:FactoryBean的单例对象的后处理失败
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
// 返回factory管理的对象实例(该对象已经过工厂的后处理)
return object;
}
}
doGetObjectFromFactoryBean()
private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
// 定义一个用于保存factory管理的对象实例的变量
Object object;
try {
// 如果有安全管理器
if (System.getSecurityManager() != null) {
// 获取访问控制的上下文对象
AccessControlContext acc = getAccessControlContext();
try {
// 以特权方式运行来获取factory管理的对象实例赋值给object
object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
// 获取factory管理的对象实例赋值给object
object = factory.getObject();
}
}
catch (FactoryBeanNotInitializedException ex) {
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}
// Do not accept a null value for a FactoryBean that's not fully
// initialized yet: Many FactoryBeans just return null then.
// 不接受尚未完全初始化的FactoryBean的null值:然后,许多FactoryBeans仅返回null
// 如果object为null
if (object == null) {
// 如果 beanName当前正在创建(在整个工厂内)
if (isSingletonCurrentlyInCreation(beanName)) {
// 抛出当前正在创建Bean异常:当前正在创建的FactoryBean从getObject返回null
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
// 让object引用一个新的NullBean实例
object = new NullBean();
}
// 返回factory管理的对象实例object
return object;
}