不同点说实话,除了名字相似外,他们似乎没有其他共同点。“BeanFactory和FactoryBean有什么区别?”BeanFactory是最基础的IOC容器,提供依赖查找、依赖注入等基础功能。FactoryBean是一种创建bean的方式,帮助实现创建复杂的bean和BeanFactory。一道高频面试题“ApplicationContext和BeanFactory有什么区别?”BeanFactory是最基础的IOC容器,提供依赖查找、依赖注入等基础功能。ApplicationContext继承了BeanFactory,增加了企业级的功能,如AOP、资源管理(Resources)事件(Event)、国际化(i18n)、环境抽象等。创建bean的方式有四种常见的创建bean的方式如下通过constructor通过静态工厂方法通过Bean工厂方法通过FactoryBean@Data@ToStringpublicclassUser{privateLongid;privateStringname;publicstaticUsercreateUser(){Useruser=newUser();user.setId(1L);user.setName("li");returnuser;}}publicclassUserFactory{publicUsercreateUser(){returnUser.createUser();}}publicclassUserFactoryBeanimplementsFactoryBean{@OverridepublicObjectgetObject()throwsException{returnUser.createUser();}@OverridepublicClass>getObjectType(){returnUser.class;}}publicclassBeanInstantiationDemo{publicstaticvoidmain(String[]args){BeanFactorybeanFactory=newClassPathXmlApplicationContext("classpath:/bean-instantiation-context.xml");Useruser1=beanFactory.getBean("user-by-constructor",User.class);Useruser2=beanFactory.getBean("user-by-static-method",User.class);Useruser3=beanFactory.getBean("user-by-factory",User.class);Useruser4=beanFactory.getBean("user-by-factory-bean",User.class);}}实现原理在分析源码之前,我们先明确两个概念“factoryBean是实现了我们在容器中配置的FactoryBean接口的bean,而subBean是用FactoryBean创建的bean。”在Spring容器的启动过程中,会实例化一个非延迟单例bean,即会调用下面的方法DefaultListableBeanFactory#preInstantiateSingletons来调用FactoryBean#getObject的链接.#getObject的调用链接可以分析一下,单tonfactoryBean对象本身会在spring容器启动时主动初始化第一次从缓存中获取factoryBean且不为空时触发subBean的初始化。如果factoryBean对象实现的接口是SmartFactoryBean,并且isEagerInit方法返回true,那么在spring容器启动的时候也会主动初始化subBean对象。如果在注册bean时,beanName对应的bean实例是一个factoryBean,那么我们通过getBean(beanName)得到的对象将是一个subBean对象;如果要获取工厂对象factoryBean,需要使用getBean("&"+beanName)singletonsubBean也会缓存在spring容器中,具体容器为FactoryBeanRegistrySupport#factoryBeanObjectCache,一个Map",推荐你看看DefaultListableBeanFactory#preInstantiateSingletons方法和FactoryBean#getObject方法的调用链接,就明白我上面说的过程了,源码我就不贴太多了。目前在Dubbbo的源码中只看到FactoryBean的应用,“服务导出:在Dubbo中,服务提供者会被封装成一个ServiceBean对象,当监听到ContextRefreshedEvent事件时,就会开始服务导出。”服务调用:服务调用者会被封装成一个ReferenceBean对象,ReferenceBean实现了FactoryBean接口和InitializingBean接口,创建subBean的逻辑在ReferenceBean#getObject方法中。“引入Dubbo服务的时机有两种,如下。》饿了么中国风:init=true,在Bean生命周期的初始化阶段会调用InitializingBean#afterPropertiesSet方法,该方法会调用ReferenceBean#getObject方法完成subBean的创建,即服务为ReferenceBean实例化时完成,懒惰风格:init=false,当ReferenceBean对应的服务注入其他类时,会调用AbstractApplicationContext#getBean获取ReferenceBean对象,因为ReferenceBean实现了FactoryBean接口,所以会调用ReferenceBean#getObject方法完成subBean的创建,即完成Service的引入{"unchecked"})publicvoidafterPropertiesSet()throwsException{/(shouldInit()){getObject();}}}本文转载自微信公众号“Java知堂”,可通过以下二维码关注。转载本文请联系Java石塘公众号。