成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

面試官:BeanFactory和FactoryBean有哪些區別?

開發 前端
通過分析DefaultListableBeanFactory#preInstantiateSingletons方法和FactoryBean#getObject的調用鏈路可以分析得到。

[[398320]]

區別

說實話,他倆除了名字比較像以外,好像沒有其他共同點了。

「BeanFactory和FactoryBean有哪些區別?」

  1. BeanFactory是一個最基礎的IOC容器,提供了依賴查找,依賴注入等基礎的功能
  2. FactoryBean是創建Bean的一種方式,幫助實現復雜Bean的創建

和BeanFactory相關的還有一個高頻的面試題

「ApplicationContext和BeanFactory有哪些區別?」

  1. BeanFactory是一個最基礎的IOC容器,提供了依賴查找,依賴注入等基礎的功能
  2. ApplicationContext繼承了BeanFactory,在BeanFactory的基礎上增加了企業級的功能,如AOP,資源管理(Resources)事件(Event),國際化(i18n),Environment抽象等

創建Bean的方式

常見的創建Bean的方式有如下四種

  1. 通過構造器
  2. 通過靜態工廠方法
  3. 通過Bean工廠方法
  4. 通過FactoryBean
  1. @Data 
  2. @ToString 
  3. public class User { 
  4.  
  5.  private Long id; 
  6.  private String name
  7.  
  8.  public static User createUser() { 
  9.   User user = new User(); 
  10.   user.setId(1L); 
  11.   user.setName("li"); 
  12.   return user
  13.  } 
  1. public class UserFactory { 
  2.  
  3.  public User createUser() { 
  4.   return User.createUser(); 
  5.  } 
  1. public class UserFactoryBean implements FactoryBean { 
  2.  
  3.  @Override 
  4.  public Object getObject() throws Exception { 
  5.   return User.createUser(); 
  6.  } 
  7.  
  8.  @Override 
  9.  public Class<?> getObjectType() { 
  10.   return User.class; 
  11.  } 
  1. <?xml version="1.0" encoding="UTF-8"?> 
  2. <beans xmlns="http://www.springframework.org/schema/beans" 
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans 
  5.         https://www.springframework.org/schema/beans/spring-beans.xsd"> 
  6.  
  7.  <!-- 構造方法實例化 Bean --> 
  8.  <bean id="user-by-constructor" class="com.javashitang.domain.User"
  9.   <property name="id" value="1"/> 
  10.         <property name="name" value="li"/> 
  11.  </bean> 
  12.  
  13.  <!-- 靜態方法實例化 Bean --> 
  14.  <bean id="user-by-static-method" class="com.javashitang.domain.User" 
  15.     factory-method="createUser"/> 
  16.  
  17.  <bean id="userFactory" class="com.javashitang.factory.UserFactory"/> 
  18.  
  19.  <!-- Bean工廠方法實例化 Bean --> 
  20.  <bean id="user-by-factory" factory-bean="userFactory" factory-method="createUser"/> 
  21.  
  22.  <!-- FactoryBean實例化 Bean --> 
  23.  <bean id="user-by-factory-bean" class="com.javashitang.factory.UserFactoryBean"/> 
  24. </beans>
  1. public class BeanInstantiationDemo { 
  2.  
  3.  public static void main(String[] args) { 
  4.   BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/bean-instantiation-context.xml"); 
  5.   User user1 = beanFactory.getBean("user-by-constructor"User.class); 
  6.   User user2 = beanFactory.getBean("user-by-static-method"User.class); 
  7.   User user3 = beanFactory.getBean("user-by-factory"User.class); 
  8.   User user4 = beanFactory.getBean("user-by-factory-bean"User.class); 
  9.  } 

實現原理

在分析源碼之前,我們先明確2個概念

「factoryBean是我們配置到容器中的實現FactoryBean接口的Bean,而subBean是用FactoryBean創建出來的Bean」

在Spring容器啟動的過程中,會實例化非延遲的單例Bean,即調用如下方法 DefaultListableBeanFactory#preInstantiateSingletons

調用FactoryBean#getObject的鏈路如下圖

通過分析DefaultListableBeanFactory#preInstantiateSingletons方法和FactoryBean#getObject的調用鏈路可以分析得到

  1. 單例的factoryBean對象本身會在spring容器啟動時主動初始化。而subBean的初始化則是在第一次從緩存中獲取factoryBean并且不為空才會觸發
  2. 如果factoryBean對象實現的接口是SmartFactoryBean且isEagerInit方法返回true,那么subBean對象也會在spring容器啟動的時候主動初始化
  3. 如果bean注冊的時候,beanName對應的bean實例是一個factoryBean,那么我們通過getBean(beanName)獲取到的對象將會是subBean對象;如果要獲取工廠對象factoryBean,需要使用getBean("&" + beanName)
  4. 單例的subBean也會緩存在spring容器中,具體的容器是FactoryBeanRegistrySupport#factoryBeanObjectCache,一個Map

「建議大家看一下DefaultListableBeanFactory#preInstantiateSingletons方法和FactoryBean#getObject方法的調用鏈路,就能理解上面我說的流程了,我就不貼太多源碼了」

應用

目前我只在Dubbbo源碼中看到了FactoryBean的應用

「服務導出:在Dubbo中,服務提供者會被包裝成ServiceBean對象,當監聽到ContextRefreshedEvent事件時開始服務導出」

「服務調用:服務調用方會被包裝成ReferenceBean對象,ReferenceBean實現了FactoryBean接口和InitializingBean接口,創建subBean的邏輯在ReferenceBean#getObject方法中」

「Dubbo服務引入的時機有如下2種?!?/p>

  1. 餓漢式:init=true,在Bean生命周期的初始化階段會調用InitializingBean#afterPropertiesSet方法,而這個方法會調用ReferenceBean#getObject方法,完成subBean的創建,即ReferenceBean實例化時完成服務引入
  2. 懶漢式:init=false,在ReferenceBean對應的服務被注入到其他類中時,此時會調用AbstractApplicationContext#getBean,獲取ReferenceBean對象,因為ReferenceBean實現了FactoryBean接口,所以會調用ReferenceBean#getObject方法,完成subBean的創建,即完成服務引入
  1. public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean, ApplicationContextAware, InitializingBean, DisposableBean { 
  2.  
  3.     @Override 
  4.     public Object getObject() { 
  5.         return get(); 
  6.     } 
  7.  
  8.     @Override 
  9.     @SuppressWarnings({"unchecked"}) 
  10.     public void afterPropertiesSet() throws Exception { 
  11.  
  12.         // 省略部分代碼 
  13.  
  14.         if (shouldInit()) { 
  15.             getObject(); 
  16.         } 
  17.     } 
  18.      

本文轉載自微信公眾號「Java識堂」,可以通過以下二維碼關注。轉載本文請聯系Java識堂公眾號。

 

責任編輯:武曉燕 來源: Java識堂
相關推薦

2025-03-10 09:30:00

SpringJava開發

2023-07-06 14:24:23

Spring接口自定義

2023-02-20 08:08:48

限流算法計數器算法令牌桶算法

2021-07-01 07:51:45

React事件綁定

2021-09-30 07:57:13

排序算法面試

2023-02-17 08:10:24

2024-04-03 15:33:04

JWTSession傳輸信息

2024-09-19 08:42:43

2024-03-07 17:21:12

HotSpotJVMHot Code

2025-03-26 01:25:00

MySQL優化事務

2024-04-19 00:00:00

計數器算法限流算法

2024-03-12 14:36:44

微服務HTTPRPC

2024-02-26 14:07:18

2025-03-10 11:40:00

前端開發HTML

2025-03-10 00:00:00

property?attributeHTML

2021-12-13 06:56:45

Comparable元素排序

2024-03-20 15:12:59

KafkaES中間件

2021-12-23 07:11:31

開發

2023-10-16 08:16:31

Bean接口類型

2024-02-01 08:08:53

Spring過濾器類型Gateway
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品3区 | 日韩在线资源 | 99色视频| 亚洲一区二区中文字幕在线观看 | 黑人精品 | 久久精品二区亚洲w码 | 久久aⅴ乱码一区二区三区 91综合网 | 国产一区二区三区在线看 | 国产精品久久av | 99热视| 国产一区免费视频 | 久久久久久久久久久爱 | 天天综合网天天综合色 | 免费一级做a爰片久久毛片潮喷 | 国产一区二区三区视频 | 欧美性精品 | 狠狠爱综合| 国产 日韩 欧美 在线 | 一级爱爱片 | 日韩精品一区二区三区在线观看 | 午夜伦理影院 | 午夜看片网站 | 日韩国产一区二区三区 | 亚洲人在线播放 | 国产精品欧美一区二区三区不卡 | 成人免费淫片aa视频免费 | 成人免费在线播放视频 | 五月婷婷视频 | 综合精品久久久 | 成人av片在线观看 | 免费视频二区 | 男人影音 | 日韩一区二区三区四区五区 | 免费久久精品视频 | 香蕉久久网 | 中文字幕一区二区三区精彩视频 | 日本a视频| 在线观看国产视频 | 国产欧美一区二区精品久导航 | 久久88| 日本精品视频在线 |