FactoryBean是bean还是Factory?


传送:

Spring大观园,我有过的困惑或许你也有!


初识
  1. FactoryBean本身就是是bean,被spring管理
  2. FactoryBean的作用是创建bean,这个创建的bean才是用户最终使用的
  3. 把FactoryBean当做是一个代理来理解,比如招个厨子来做饭:我想吃饭,我自己不做,招个厨子来做。
    我自己买食材做好饭,放到spring,要吃饭的时候从spring里拿饭
    我花钱雇个厨子,放到spring,要吃饭的时候从spring里找厨子要,厨子做好饭给我。
public interface FactoryBean {
    //通过此方法创建对象
    T getObject() throws Exception;

    // 指定返回对象的类型
    Class getObjectType();

    // true 单态,从FacotoryBean得到的是同一对象
    // false 从FactoryBean得到的是不同的对象。
    default boolean isSingleton() {
        return true;
    }
}
疑问

为什么会有创建bean的bean??什么情况下使用

  • 举例
    比如一个三方库最终目的是提供bean,这个bean的创建依赖于一些属性配置,使用属性配置 调用N多API,才能完成bean的创建。
    从使用角度来看,spring的直接用户提供属性配置,给三方库,三方库自己调用N多API把bean的创建后,返回给直接用户就好,如何调用api创建,对用户透明。

类比到FactoryBean来看,

  1. 三方库提供一个FactoryBean.
  2. 用户把属性配置给这个FactoryBean.
  3. 三方库FactoryBean在getObject方法中根据属性配置,完成bean的创建
  4. 用户从spring中获取到最终自己使用的bean,而不是FactoryBean.
  • 总结
  1. 用户最终使用的是FactoryBean所创建的bean
  2. 创建bean的一些参数需要用户来提供,创建bean的过程不需要用户关注
  3. Bean的提供方,需要提供一个对象让用户对其操作,传入参数,这个对象就是FactoryBean.
  4. 创建bean的过程就是FactoryBean内部的getObject方法。
  5. spring的Bean有scope的概念,FactoryBean内部的isSingleton负责实现这个scope的功能。
两种bean如何获取

applicationContext.getBean("&FactoryBean名称") 获取FactoryBean对象
applicationContext.getBean("FactoryBean名称") 获取FactoryBean的getObject所创建的对象

public class Person {
}
@Component
public class PersonFactoryBean implements FactoryBean {
    @Override
    public Person getObject() throws Exception {
        return new Person();
    }

    @Override
    public Class getObjectType() {
        return Person.class;
    }
}
  

@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringbootLearnApplication.class)
public class SpringbootLearnApplicationTests {

    @Autowired
    private ApplicationContext applicationContext;
    @Autowired
    private PersonFactoryBean personFactoryBean;
    @Autowired
    private Person person;
    @Test
    public void testFactoryBean() {

        try {
            System.out.println(applicationContext.getBean("&personFactoryBean") == personFactoryBean); // true
            System.out.println(applicationContext.getBean("personFactoryBean") == person);//true
            System.out.println("");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

你可能感兴趣的:(FactoryBean是bean还是Factory?)