spring中的FactoryBean与ObjectFactory的区别

    科技2025-01-21  41

    一、接口定义 :

    public interface FactoryBean<T> { //获取对象的工厂方法 @Nullable T getObject() throws Exception; //对象类型 @Nullable Class<?> getObjectType(); //是否是单例,这个属性决定了spring是否基于缓存来将它维护成一个单例对象。 default boolean isSingleton() { return true; } } public interface ObjectFactory<T> { //获取对象的工厂方法。 T getObject() throws BeansException; }

    通过接口内容来看,两者都是属于工厂模式用来创建对象使用的。 而区别在于 FactoryBean在BeanFacotry的实现中有着特殊的处理,如果一个对象实现了FactoryBean 那么通过它get出来的对象实际是 factoryBean.getObject() 得到的对象,如果想得到FactoryBean必须通过在 '&' + beanName 的方式获取

    而ObjectFactory则只是一个普通的对象工厂接口。 在查看AbstractBeanFacotry的doGetBean(..) 部分的源码时,可以看到spring对ObjectFactory的应用之一就是,将创建对象 的步骤封装到ObjectFactory中 交给自定义的Scope来选择是否需要创建对象来灵活的实现scope。

    通过这方面简单的对比可以得到:

        FactoryBean的着重于自定义创建对象过程,由BeanFactory通过FactoryBean来获取目标对象,而如果是isSingleton返回true的     话spring会利用单例缓存来缓存通过FactoryBean创建的对象。

        而ObjectFactory就是一个普通的工厂对象接口,对于spring在doGetBean处的使用时,在于创建对象的过程由框架通过ObjectFactory定义,而     创建的时机交给拓展接口Scope,除此之外ObjectFactory就是一个普通的接口。     此外在将给依赖注入列表注册一个ObjectFactory类型的对象,在注入过程中会调用objectFactory.getObject()来创建目标对象注入进去。     (如beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory());)

        简单来说就是通过FactoryBean你可以控制对象如何创建,而ObjectFactory借助Scope接口自定义scope你可以控制对象的创建时机。

    三、例子:

    car.java

    public class Car { private int maxSpeed; private String brand; private double price; public int getMaxSpeed() { return maxSpeed; } public void setMaxSpeed(int maxSpeed) { this.maxSpeed = maxSpeed; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } @Override public String toString() { return "Car{" + "maxSpeed=" + maxSpeed + ", brand='" + brand + '\'' + ", price=" + price + '}'; } } CarFactoryBean.java public class CarFactoryBean implements FactoryBean<Car> { @Override public Car getObject() throws Exception { Car car = new Car(); car.setMaxSpeed(260); car.setBrand("宝马"); car.setPrice(500000); return car; } @Override public Class<?> getObjectType() { return Car.class; } @Override public boolean isSingleton() { return true; } }

     spring-config.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="carFactoryBean" class="hong.factoryBean.CarFactoryBean" > </bean> </beans>

     

    Test.java

    public class Test { public static void main(String args[]) { Resource resource = new ClassPathResource("hong/factoryBean/spring-config.xml"); BeanFactory beanFactory = new XmlBeanFactory(resource); System.out.println(beanFactory.getBean("carFactoryBean").toString()); System.out.println(beanFactory.getBean("&carFactoryBean").toString()); } }

    Processed: 0.022, SQL: 8