核心内容拆解 FactoryBean
FactoryBean 接口,使得我们可以通过编写自定义代码来实现 Bean 的实例化和注入。具体来说,通过实现 FactoryBean 接口,我们可以在 getObject () 方法中编写自己的逻辑来实例化 Bean,同时可以在 getObjectType () 方法中指定返回的类型。因此,FactoryBean 的主要作用是对 Bean 的创建过程进行个性化定制,使得我们能够更好地控制 Spring 容器中 Bean 的生命周期和行为。同时,它还可以支持单例模式或者原型模式的 Bean 创建方式,更进一步增强了 Spring 容器的灵活性。
public interface FactoryBean<T> {
// 获取对象
T getObject() throws Exception;
// 获取对象类型
Class<?> getObjectType();
// 判断是否单例
boolean isSingleton();
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
在 《核心功能拆解 IOC》 一文中,当一个 Bean 对象的创建结束,并得到所创建的 Bean 后,会继续执行 getObjectForBeanInstance 方法
protected <T> T doGetBean(final String name, final Object[] args) {
// 从缓存中获取实例
Object sharedInstance = getSingleton(name);
if (sharedInstance != null) {
// 如果实现了 FactoryBean,则需要调用 FactoryBean#getObject
return (T) getObjectForBeanInstance(sharedInstance, name);
}
// 从BeanDefinition列表中获取对象
BeanDefinition beanDefinition = getBeanDefinition(name);
Object bean = createBean(name, beanDefinition, args);
// 如果实现了 FactoryBean,则需要调用 FactoryBean#getObject
return (T) getObjectForBeanInstance(bean, name);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
该方法用于判断一个 Bean 是否实现了 FactoryBean 接口,如果实现了接口则需要进行对应的操作
private Object getObjectForBeanInstance(Object beanInstance, String beanName) {
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
// 查询 Bean 是否已被执行过
Object object = getCachedObjectForFactoryBean(beanName);
if (object == null) {
// 转成 FactoryBean
FactoryBean<?> factoryBean = (FactoryBean<?>) beanInstance;
// 具体执行
object = getObjectFromFactoryBean(factoryBean, beanName);
}
return object;
}
protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName) {
// 判断是否单例,单例会添加到 factoryBeanObjectCache 改该Map中,避免重复
if (factory.isSingleton()) {
// 获取
Object object = this.factoryBeanObjectCache.get(beanName);
// 判断是否存在
if (object == null) {
// 执行
object = doGetObjectFromFactoryBean(factory, beanName);
this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
}
return (object != NULL_OBJECT ? object : null);
} else {
return doGetObjectFromFactoryBean(factory, beanName);
}
}
private Object doGetObjectFromFactoryBean(final FactoryBean factory, final String beanName){
try {
// 调用接口方法
return factory.getObject();
} catch (Exception e) {
throw new BeansException("FactoryBean threw exception on object[" + beanName + "] creation", e);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
这种方式可以理解为,实现 FactoryBean 的类是一个代理类,他的工作主要是在自己被创建的时候,按照 Spring 的生命周期,创建自己的实例,填充属性,初始化之前执行,初始化执行,初始化之后执行,这一切都只是为被代理类做好条件铺设,等这个代理类创建完毕后,会执行 getObjectForBeanInstance 方法,返回被代理的类。更简单的理解就是 FactoryBean 可以帮我们制造我们想要的 Bean,供其他 Bean 依赖或使用。
上次更新: 4/1/2025, 5:03:02 PM