(六)关于spring中的FactoryBean与ObjectFactory以及其区别

1.查看接口定义以及其区别

public interface FactoryBean<T> {
    //获取对象的工厂方法
    @Nullable
    T getObject() throws Exception;
    //对象类型
    @Nullable
    Class<?> getObjectType();
    //是否是单例,这个属性决定了spring是否基于缓存来将它维护成一个单例对象。
    default boolean isSingleton() {
        return true;
    }
}
@FunctionalInterface
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你可以控制对象如何创建,而借助Scope接口自定义scope你可以控制对象的创建时机。

2.demo

@Configuration
public class Application {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Application.class);
        ConfigurableListableBeanFactory beanFactory = (ConfigurableListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
        //注册可被注入实例
        beanFactory.registerResolvableDependency(Person.class, new StudentObjectFactory());
        //添加BeanDefinition
        RootBeanDefinition objectXDef = new RootBeanDefinition(ObjectX.class);
        objectXDef.setScope(BeanDefinition.SCOPE_PROTOTYPE);
        applicationContext.registerBeanDefinition("objectX", objectXDef);
        //输出com.example.lcc.basic.spring.factory.Application$Person@4f51b3e0
        System.out.println(applicationContext.getBean("objectX", ObjectX.class).person);

        //输出com.example.lcc.basic.spring.factory.Application$Man@282003e1
        System.out.println(applicationContext.getBean("myFactoryBean"));
        //true 多次获取都是同一个对象
        System.out.println(applicationContext.getBean("myFactoryBean") == applicationContext.getBean("myFactoryBean"));
        //获取实际的工厂对象
        //输出com.example.lcc.basic.spring.factory.Application$MyFactoryBean@7fad8c79
        System.out.println(applicationContext.getBean("&myFactoryBean"));
    }

    @Bean
    public FactoryBean<Man> myFactoryBean(){
        return new MyFactoryBean();
    }

    public static class MyFactoryBean implements FactoryBean<Man>{

        @Override
        public Man getObject() throws Exception {
            return new Man();
        }

        @Override
        public Class<?> getObjectType() {
            return Man.class;
        }

        @Override
        public boolean isSingleton() {
            return true;
        }
    }

    public static class ObjectX {
        @Autowired
        Person person;
    }
    public static class Person {

    }
    public static class Man {

    }

    public static class StudentObjectFactory implements ObjectFactory<Person> {

        @Override
        public Person getObject() throws BeansException {
            return new Person();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/m0_38043362/article/details/80284577