什么是FactoryBean?别动不动就比较它和BeanFactory的区别,很显然前者是一个bean,而后者是一个是factory。既然是一个bean,又是在spring中,差不多很可能就是用来创建bean的,bean最后还是要进factory的。下来看下FactoryBean接口信息。
public interface FactoryBean<T> {
@Nullable
T getObject() throws Exception;
@Nullable
Class<?> getObjectType();
default boolean isSingleton() {
return true;
}
}
接口比较简单,有两个待实现的方法分别用来返回实例对象和对象类型,一个返回true的默认单实例方法。下面通过FactoryBean来实例化自己的bean。
import org.springframework.beans.factory.FactoryBean;
public class BirdFactoryBean implements FactoryBean<Bird> {
@Override
public Bird getObject() {
return new Bird();
}
@Override
public Class<?> getObjectType() {
return Bird.class;
}
}
class Bird{
}
就用FactoryBean返回一只鸟,然后把BirdFactoryBean进行实例化,采用古老的方式@Bean。
@Bean
public BirdFactoryBean birdFactoryBean(){
return new BirdFactoryBean();
}
我们知道通过注解@Bean创建的bean默认的name是方法名,下面使用方法名来获取bean对象,看看拿到的是什么。
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);
Object o1 = applicationContext.getBean("birdFactoryBean");
System.out.println(o1.getClass());
--class com.star.model.Bird
Object o2 = applicationContext.getBean("&birdFactoryBean");
System.out.println(o2.getClass());
--class com.star.condition.BirdFactoryBean
可以看到直接使用beanName获取得到的是自定义FactoryBean的getObject方法返回的实例,而使用&beanName获取得到的是FactoryBean自身。当然这里也可以直接通过类型获取目标对象,&是spring指定的前缀,这里的beanName间接引用(dereference)了目标对象。源代码也比较清晰,打个断点一目了然。
通过FactoryBean可以更灵活创建更为复杂的bean,比如spring AOP 中的ProxyFactoryBean,比如加载属性文件的PropertiesFactoryBean......