FactoryBean和BeanFactory都是spring的一个类工厂,BeanFactory只能生产一种类型的类,FactoryBean可以生产两种类型的类,一种跟BeanFactory类似,生产的是当前对象,另一种是通过getObject()返回的对象。
FactoryBean要返回当前本身的对象时,需要在getBean()时,在获取的对象前面加&,如:getBean("&daoFactoryBean")。当一个类依赖关系很复杂的时候,而我们有需要使用这个类对象时采用FactoryBean获取。如我们mybatis中经常使用的sqlSessionFactory 对象,他就是通过 SqlSessionFactoryBean实现FactoryBean,通过getObject()方法获取的。
FactoryBean通过getObject()获取对象示例如下:
@Component("daoFactoryBean")
public class DaoFactoryBean implements FactoryBean {
public void testBean(){
System.out.println("testBean");
}
@Override
public Object getObject() throws Exception {
return new TempDaoFactoryBean();
}
public Class<?> getObjectType() {
return TempDaoFactoryBean.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
public class TempDaoFactoryBean {
public void test(){
System.out.println("FactoryBean");
}
}
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(Appconfig.class);
TempDaoFactoryBean temp = (TempDaoFactoryBean)ac.getBean("daoFactoryBean");
temp.test();
}
}
运行结果:FactoryBean
FactoryBean获取本身对象示例:
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(Appconfig.class);
DaoFactoryBean temp = (DaoFactoryBean)ac.getBean("&daoFactoryBean");
temp.testBean();
}
}
运行结果:testBean
BeanFactory
spring对外暴露的ApplicationContext作为IOC容器最重要的接口它也实现了BeanFactory接口(ApplicationContext->ListableBeanFactory->BeanFactory)
BeanFactory接口:它是IoC容器的顶级接口,是IoC容器的底层基础实现,也是访问Spring容器的根接口,负责对bean的创建,访问等工作。
结构视图如下:
FactoryBean
FactoryBean接口:它是一个可以返回bean的实例的工厂bean,实现这个接口可以对bean进行一些额外的操作,例如根据不同的配置类型返回不同类型的bean,简化xml配置等。
它在使用上也有些特殊,BeanFactory接口中有一个字符常量String FACTORY_BEAN_PREFIX = "&"; 当我们去获取BeanFactory类型的bean时,如果beanName不加&则获取到对应bean的实例;如果beanName加上&,则获取到BeanFactory本身的实例。
/** * Interface to be implemented by objects used within a {@link
BeanFactory} which * are themselves factories for individual objects. If a bean
implements this * interface, it is used as a factory for an object to expose,
not directly as a * bean instance that will be exposed itself. * *
NB: A bean that implements this interface cannot be used as a normal
bean. * A FactoryBean is defined in a bean style, but the object exposed for
bean * references ({@link #getObject()}) is always the object that it
creates.
如上:在一个spring配置文件中配置了名字为 myFcBean 的一个类型,该类型是 FactoryBean 的实现类。那么通过BeanFactory.getBean(“myFcBean”) 返回的就并不是这个类型本身的对象,而是调用这个对象的getObject方法的返回值。
结构视图如下:
区别:BeanFactory是个Factory,也就是IOC容器或对象工厂,而FactoryBean就是个Bean。在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理的。但对FactoryBean而言,这个Bean不是简单的Bean,而是一个能生产或者修饰对象生成的工厂Bean,它的实现与设计模式中的工厂模式和修饰器模式类似。
以上就是关于beanfactory和factorybean之间区别的所有内容了。