BeanFactory

BeanFactory, 它是负责生产和管理 bean 的一个工厂。也可以理解为 bean 的注册中心。它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。他是IOC容器的核心接口之一。它有很多实现类如:DefaultListableBeanFactory

FactoryBean

官方文档: Customizing Instantiation Logic with a FactoryBean
image.png
基本描述

  • FactoryBean 也是一个由 Spring 容器管理的类,其可以通过 BeanFactory 的 getBean 方法获得;
  • 它起到一个工厂的作用,可以通过 getObject 来生产 bean ;
  • 在首字母小写前面加一个&符号,获得的是 FactoryBean 实例;
  • FactoryBean 不支持依赖注入,它调用时机在 Spring 初始化的早期进行,此时还没有生成要依赖的对象;
  • 调用时该 FactoryBean 尚未完全初始化,则抛出相应的FactoryBeanNotInitializedException;

存在的原因?
spring 通过 xml 配置或者注解,利用反射等机制已经能实现 bean 的实例化,为什么还需要 FactoryBean 来生产 bean ?

  • 首先 通过配置文件来配置 bean ,在一些复杂的情况下,配置并不能满足各种各样的需求,如果使用FactoryBean,通过接口注册,就能通过代码自定义实现各种复杂 bean 的实例化。
  • 除外,通过接口也给了第三方扩展的可能。

测试代码
自定义个 FactoryBean

  1. public class UserFactoryBean implements FactoryBean<User> {
  2. private static final User instance = new User();
  3. @Override
  4. public User getObject() throws Exception {
  5. instance.setName("nb!");
  6. return instance;
  7. }
  8. @Override
  9. public Class<?> getObjectType() {
  10. return User.class;
  11. }
  12. }

注册 bean

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "https://www.springframework.org/dtd/spring-beans-2.0.dtd">
  3. <beans>
  4. <bean id="userFactoryBean" class="cn.lichenghao.factory.UserFactoryBean"></bean>
  5. </beans>

测试

  1. public class AppFactoryBean {
  2. public static void main(String[] args) {
  3. // 根据配置文件加载bean
  4. ClassPathXmlApplicationContext context
  5. = new ClassPathXmlApplicationContext("factoryBean.xml");
  6. // 直接获取userFactoryBean得到的是其getObject返回的对象
  7. Object obj1 = context.getBean("userFactoryBean");
  8. // 加&前缀,获取到FactoryBean实例
  9. Object obj2 = context.getBean("&userFactoryBean");
  10. System.out.println(obj1);
  11. System.out.println(obj2);
  12. }
  13. }
  14. // 运行结果
  15. > Task :spring-lich-test:AppFactoryBean.main()
  16. User{name='nb!', age='null'}
  17. cn.lichenghao.factory.UserFactoryBean@1e88b3c