BeanFactory和FactoryBean的区别

120 阅读3分钟

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之间区别的所有内容了。