内容介绍
在 Spring 框架中,FactoryBean
是一个特殊的工厂类接口,用于创建和管理复杂的 bean 对象。它允许你自定义 bean 的创建逻辑,并且可以在 bean 创建过程中执行一些额外的操作。FactoryBean
接口通常用于创建那些非常复杂或需要特殊处理的 bean 实例,例如连接池、远程服务代理等。
当我们向容器中获取FactoryBean时,容器返回的不是他本身,而是他的getObject()方法的返回值。
FactoryBean
接口有两个核心方法:
-
T getObject()
:该方法负责创建和返回一个 bean 实例。你可以在这个方法中编写自定义的 bean 创建逻辑。 -
Class<?> getObjectType()
:该方法返回工厂创建的 bean 的类型。通常,它用于告诉 Spring 容器工厂创建的 bean 类型是什么。
代码分支
核心代码
FactoryBean接口
public interface FactoryBean<T> {
T getObject() throws Exception;
boolean isSingleton();
}
AbstractBeanFactory
在getBean方法中添加BeanFactory的逻辑,当bean属于BeanFactory类型的,就拿他的getObject方法返回的对象,并根据isSingleton()方法返回时决定是否加入缓存。
....
用于缓存单例的BeanFactory提供类
private final Map<String, Object> factoryBeanObjectCache = new HashMap<>();
private Object getObjectForBeanInstance(Object sharedInstance, String beanName) throws Exception {
Object obj = sharedInstance;
if(sharedInstance instanceof FactoryBean){
try {
FactoryBean factoryBean = (FactoryBean<?>)sharedInstance;
if(((FactoryBean<?>)sharedInstance).isSingleton()){
//singleton作用域bean,从缓存中获取
obj = this.factoryBeanObjectCache.get(beanName);
if( obj == null ){
obj = factoryBean.getObject();
this.factoryBeanObjectCache.put(beanName, obj);
}
}else{
//prototype作用域bean,新创建bean
obj = factoryBean.getObject();
}
}catch (Exception e){
throw new BeansException("FactoryBean threw exception on object[" + beanName + "] creation", e);
}
}
return obj;
}
....
测试
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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<bean id="person" class="bean.PersonFactoryBean">
<property name="name" value="yiHuiGoGoGO"/>
</bean>
</beans>
FactoryBean
public class PersonFactoryBean implements FactoryBean<Person> {
private String name;
@Override public Person getObject() {
Person person = new Person();
person.setName("YiHuiComeOn");
person.setAge("18");
return person;
}
@Override public boolean isSingleton() {
return true;
}
....
测试类
@Test
public void testFactoryBean(){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:factory-bean.xml");
Person person = applicationContext.getBean("person", Person.class);
System.out.println(person);
}
测试结果
输出的确实是getObject返回的类,而不是类本身。
Person{name='YiHuiComeOn', age='18', car=null}