【Spring原始碼閱讀】 DefaultListableBeanFactory繼承結構講解分析
在基於ClassPathXmlApplicationContext建立BeanFactory時,我們從程式碼裡看到,建立的BeanFactory的型別是DefaultListableBeanFactory。
下面我們來分析下DefaultListableBeanFactory的繼承結構,以及基於這個結構下,每個父類介面的用途。
具體UML類圖實現如下:
下面開始從頂層實現類開始,依次向下逐層分析:
DefaultListableBeanFactory實現
實現介面向上可以追述至BeanFacotry,向下還有XmlBeanFactory實現,但從整個繼承結構來看,從DefaultListableBeanFactory開始可以作為獨立的IOC容器。
分析原始碼,在DefaultListableBeanFactory中定義了以下屬性
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
/** 儲存對映serializedId->DefaultListableBeanFactory的弱引用例項*/
private static final Map<String, Reference<DefaultListableBeanFactory> > serializableFactories =
new ConcurrentHashMap<String, Reference<DefaultListableBeanFactory>>(8);
/** 當前工廠的可選序列化id */
private String serializationId;
/** 是否允許同名的不同bean definition再次進行註冊
* 在註冊BeanDefinition發現存在同名BeanDefinition時,會檢查當前變數,如果為false會丟擲BeanDefinitionStoreException */
private boolean allowBeanDefinitionOverriding = true;
/** 是否允許eager類(相對於lazy)的載入,甚至延遲初始化的bean的載入,
* 主要用於在呼叫doGetBeanNamesForType輔助尋找符合type要求的beanName */
private boolean allowEagerClassLoading = true;
/**是一個策略介面,用來決定一個特定的bean definition 是否滿足做一個特定依賴的自動繫結的候選項
* 裡面定義了isAutowireCandidate方法用來判斷一個Bean是否參與自動裝配候選以及getSuggestedValue方法找出最佳候選Bean*/
private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver();
/** 定義了依賴型別和其對應的依賴注入物件鍵值對集合。 */
private final Map<Class<?>, Object> resolvableDependencies = new HashMap<Class<?>, Object>(16);
/** 定義了BeanName->BeanDefinition的對映關係 */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);
/** 定義了依賴型別->BeanNames的對映關係,包括單例和原型Bean
* 具體儲存原理是先根據BeanName讀取beanDefinitionNames物件或frozenBeanDefinitionNames物件
* 再呼叫getMergedLocalBeanDefinition(beanName)方法拿到具體的BeanDefinition,比對BeanClass,滿足要求的都儲存到List統一返回*/
private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);
/** 類似於allBeanNamesByType,不過只包含單例Bean */
private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);
/** 根據註冊順序,儲存所有的beanDefinitionName,即beanName */
private final List<String> beanDefinitionNames = new ArrayList<String>(64);
/** 配置是否凍結 在初始化完BeanFactory,開始初始化所有單例非懶載入Bean時呼叫finishBeanFactoryInitialization方法進行凍結*/
private boolean configurationFrozen = false;
/** 在設定上一布林變數同時快取當前時刻的所有beanDefinitionNames到當前屬性 */
private String[] frozenBeanDefinitionNames;
}
在DefaultListableBeanFactory內部,實現了ListableBeanFactory、ConfigurableListableBeanFactory、BeanDefinitionRegistry的相關介面,同時還實現瞭解析依賴,查到最佳的依賴注入BeanName等。
具體實現的方法可參照下圖:
ConfigurableListableBeanFactory
ConfigurableListableBeanFactory定義bean definition的解析,修改等方法功能,還定義了初始化非懶載入單例Bean的核心方法preInstantiateSingletons.
具體介面定義如下:
public interface ConfigurableListableBeanFactory
extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory {
/**
* 忽略指定型別的自動裝配
* @param type 要忽略的依賴型別
*/
void ignoreDependencyType(Class<?> type);
/**
* 在自動裝配時忽略該介面實現類中和setter方法入參相同的型別
* 在進行依賴注入時,會獲取待注入屬性的set方法,如果set方法的入參實現了本介面,會忽略該屬性的依賴注入
* 具體參考https://www.jianshu.com/p/3c7e0608ff1f
* @param ifc 要進行據略的介面
*/
void ignoreDependencyInterface(Class<?> ifc);
/**
* 建議一個依賴型別->自動裝配Bean的對映關係
* @param dependencyType 依賴型別
* @param autowiredValue 對應的裝配例項,也可以是ObjectFactory的實現,會呼叫其中的getObject方法完成攔截在.
*/
void registerResolvableDependency(Class<?> dependencyType, Object autowiredValue);
/**
* 判斷特定的bean是否可以作為一個自動裝配的候選Bean
* @param beanName 待檢查的BeanName
* @param descriptor 待解析的依賴引數的描述器
* @return 返回是否可以作為候選Bean
* @throws NoSuchBeanDefinitionException 如果沒有BeanName對應的BeanDefinition
*/
boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
throws NoSuchBeanDefinitionException;
/**
* 根據BeanName獲取具體的BeanDefinition
*/
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
/**
* 凍結配置
*/
void freezeConfiguration();
/**
* 判斷相關配置是否已凍結
*/
boolean isConfigurationFrozen();
/**
* 初始化所有非懶載入的單例Bean,相應的通過呼叫destroySingletons方法銷燬本方法註冊的單例
*/
void preInstantiateSingletons() throws BeansException;
}
ListableBeanFactory
繼承自BeanFactory介面,定義了迭代列舉容器Bean例項的相關方法,具體定義如下:
public interface ListableBeanFactory extends BeanFactory {
/**
* 容器是否定義了指定beanName的
*/
boolean containsBeanDefinition(String beanName);
/**
* 獲取BeanDefinition數量
*/
int getBeanDefinitionCount();
/**
* 獲取所有的BeanDefinition的BeanName
*/
String[] getBeanDefinitionNames();
/**
* 獲取指定型別的所有BeanNames,預設包含非單例(原型Bean),允許提前初始化,可能會導致實現FactoryBean介面的Bean提前初始化
*/
String[] getBeanNamesForType(Class<?> type);
/**
* 獲取指定型別的所有BeanNames
* @param type 要獲取BeanName的型別
* @param includeNonSingletons 是否包含包含非單例(原型Bean)
* @param allowEagerInit 允許提前初始化,可能會導致實現FactoryBean介面的Bean提前初始化
*/
String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);
/**
* 獲取指定型別的的beanName->bean例項對映,預設包含非單例(原型Bean),允許提前初始化,可能會導致實現FactoryBean介面的Bean提前初始化
*/
<T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException;
/**
* 獲取指定型別的的beanName->bean例項對映
* @param type 要獲取BeanName的型別
* @param includeNonSingletons 是否包含包含非單例(原型Bean)
* @param allowEagerInit 允許提前初始化,可能會導致實現FactoryBean介面的Bean提前初始化
*/
<T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
throws BeansException;
/**
* 獲取帶有指定註解型別的beanName->bean例項對映
*/
Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType)
throws BeansException;
/**
* 根據註解型別和beanName獲取相關的Bean註解例項
*/
<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType);
}
AbstractAutowireCapableBeanFactory
在本類中定義了Spring容器的幾乎最核心的實現邏輯,包括例項化bean和依賴注入的具體實現等。
在本類,基本的屬性定義如下所示:
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
/** 例項化Bean的策略,預設是CglibSubclassingInstantiationStrategy,
* 對於實現了lookup-method或replace-method,會通過當前策略生成的CGLIB代理類增強呼叫相應的方法*/
private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
/** 預設的方法引數名字解析策略 */
private ParameterNameDiscoverer parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();
/** 是否允許出現迴圈引用,如果為false,在例項化Bean後不會放入單例工廠中以提前暴露給其他Bean依賴注入 */
private boolean allowCircularReferences = true;
/**
* 是否在迴圈引用的情況下注入原始bean例項,即使注入的bean最終被包裝。
*/
private boolean allowRawInjectionDespiteWrapping = false;
/**
* 儲存在依賴注入時要忽略的類
*/
private final Set<Class<?>> ignoredDependencyTypes = new HashSet<Class<?>>();
/**
* 儲存在自動裝配時,要忽略的在setter方法中實現本介面的入參
*/
private final Set<Class<?>> ignoredDependencyInterfaces = new HashSet<Class<?>>();
/** 快取FactoryBean name 到具體的FactoryBean例項(具體表現為對映BeanWrapper)*/
private final Map<String, BeanWrapper> factoryBeanInstanceCache =
new ConcurrentHashMap<String, BeanWrapper>(16);
/** 快取根據ignoredDependencyTypes,ignoredDependencyInterfaces條件過濾的特定Bean類的屬性描述器*/
private final Map<Class<?>, PropertyDescriptor[]> filteredPropertyDescriptorsCache =
new ConcurrentHashMap<Class<?>, PropertyDescriptor[]>(64);
}
AbstractAutowireCapableBeanFactory實現的方法相當多而複雜,總結來說,AbstractAutowireCapableBeanFactory實現了Spring容器例項化、依賴注入Bean相關屬性、初始化Bean等相關方法,具體定義的方法可參照下圖:
AutowireCapableBeanFactory
定義提供了BeanFacotry實現了依賴注入的功能,定義了依賴注入型別的相關列舉,內部包含以下常量屬性:
public interface AutowireCapableBeanFactory extends BeanFactory {
/**
* 不使用自動裝配,不影響通過xml配置或註解等方式的顯式依賴注入配置
*/
int AUTOWIRE_NO = 0;
/**
* 在初始化容器內Bean的時候,檢索出Bean內可以進行依賴注入的屬性,然後根據名字檢索容器內的Bean進行注入
*/
int AUTOWIRE_BY_NAME = 1;
/**
* 在初始化容器內Bean的時候,檢索出Bean內可以進行依賴注入的屬性,然後根據型別檢索容器內的Bean進行注入
*/
int AUTOWIRE_BY_TYPE = 2;
/**
* 檢索最符合的構造方法,對建構函式內的入參進行依賴注入,再傳入建構函式
*/
int AUTOWIRE_CONSTRUCTOR = 3;
/**
* 自動探測,如果Bean內有無參建構函式,則用AUTOWIRE_BY_TYPE,否則用AUTOWIRE_CONSTRUCTOR
*/
@Deprecated
int AUTOWIRE_AUTODETECT = 4;
}
AutowireCapableBeanFactory介面定義的方法主要涵蓋建立、初始化Bean並在初始化前後呼叫相應的後置處理器,解析依賴,完成依賴注入等功能。
具體內部方法參照下圖:
AbstractBeanFactory
BeanFactory的抽象實現,繼承自FactoryBeanRegistrySupport。提供了單例物件管理、父子容器管理,BeanDefinition管理和FactoryBean註冊管理等相關功能,AbstractBeanFactory具體定義的屬性如下:
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
/** 父容器,為BeanFactory提供繼承能力 */
private BeanFactory parentBeanFactory;
/** 必要時用於解析載入bean類,當tempClassLoader=null時使用 */
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
/**必要時用於臨時解析載入bean類,在預載入非攔截在單例Bean的凍結配置前使用*/
private ClassLoader tempClassLoader;
/** 是否快取bean元資料,或者每次訪問重新獲取,如果為true,每次呼叫getMergedBeanDefinition後必要時會快取到mergedBeanDefinitions */
private boolean cacheBeanMetadata = true;
/** 表示式解析策略,用於解析beanDefinition中的表示式如SpEL等 */
private BeanExpressionResolver beanExpressionResolver;
/** 在屬性編輯(讀寫)過程通過ConversionService完成屬性的型別轉換,預設全部屬性為String型別,最終轉換成各種物件型別*/
private ConversionService conversionService;
/** 自定義屬性編輯器註冊商,持有屬性編輯器的註冊器,通過呼叫registerCustomEditors方法完成批量註冊拓展的自定義屬性編輯器的邏輯*/
private final Set<PropertyEditorRegistrar> propertyEditorRegistrars =
new LinkedHashSet<PropertyEditorRegistrar>(4);
/** 自定義TypeConverter,重寫預設的PropertyEditor機制,定義了屬性轉換的機制 */
private TypeConverter typeConverter;
/** 自定義屬性編輯器,用於編輯容器內的Bean屬性
* 呼叫鏈是通過createBean->doCreateBean->populateBean->applyPropertyValues->TypeConverter.convertIfNecessary進行 */
private final Map<Class<?>, Class<? extends PropertyEditor>> customEditors =
new HashMap<Class<?>, Class<? extends PropertyEditor>>(4);
/** 用於諸如註解屬性的字串解析器 */
private final List<StringValueResolver> embeddedValueResolvers = new LinkedList<StringValueResolver>();
/** 儲存例項化和初始化Bean過程用到的Bean後置處理器BeanPostProcessors to apply in createBean */
private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<BeanPostProcessor>();
/** 標誌容器內是否註冊了InstantiationAwareBeanPostProcessors */
private boolean hasInstantiationAwareBeanPostProcessors;
/** 標誌容器內是否註冊了destructionAwareBeanPostProcessors */
private boolean hasDestructionAwareBeanPostProcessors;
/** 建立字串型別->Scope的對映關係
* 具體用例如registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope())
* */
private final Map<String, Scope> scopes = new HashMap<String, Scope>(8);
/** 容器內執行的安全上下文的提供者 */
private SecurityContextProvider securityContextProvider;
/** 建立BeanName->RootBeanDefinition的對映關係 */
private final Map<String, RootBeanDefinition> mergedBeanDefinitions =
new ConcurrentHashMap<String, RootBeanDefinition>(64);
/** 記錄特定BeanName的bean已經建立過至少一次 */
private final Map<String, Boolean> alreadyCreated = new ConcurrentHashMap<String, Boolean>(64);
/** 記錄當前處於建立狀態的Bean */
private final ThreadLocal<Object> prototypesCurrentlyInCreation =
new NamedThreadLocal<Object>("Prototype beans currently in creation");
}
ConfigurableBeanFactory
提供配置管理Bean的能力,定義了Bean作用域的基礎型別,包括singleton和prototype,繼承自HierarchicalBeanFactory, SingletonBeanRegistry,具有父子容器繼承和單例Bean註冊等相關能力
FactoryBeanRegistrySupport
提供了FacotryBean型別Bean的註冊管理,定義了一個ConcurrentHashMap建立了beanName->FactoryBean的快取。
具體實現如下:
public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {
/** 建立BeanName->factoryBeanObject的快取對映 */
private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<String, Object>(16);
/**
* 呼叫factoryBean.getObjectType()獲取實現了FactoryBean介面的相應例項方法.
*/
protected Class<?> getTypeForFactoryBean(final FactoryBean<?> factoryBean);
/**
* 嘗試從快取中獲取FactoryBeanObject
*/
protected Object getCachedObjectForFactoryBean(String beanName);
/**
* 獲取當前factory的實際例項物件,會先嚐試從快取獲取,再通過呼叫doGetObjectFromFactoryBean獲取
*/
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess);
/**
* 真正獲取物件的方法,通過呼叫factory.getObject()
*/
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException;
/**
* 預設實現是直接返回入參Object,子類可以自行拓展,如新增Bean後置處理器邏輯等
*/
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) throws BeansException {
return object;
}
/**
* 判斷beanInstance是否是FactoryBean例項,如果是則進行型別轉換返回.
*/
protected FactoryBean<?> getFactoryBean(String beanName, Object beanInstance) throws BeansException;
/**
* 先呼叫父類removeSingleton,並嘗試從當前factoryBean快取中移除特定Bean
*/
@Override
protected void removeSingleton(String beanName);
/**
* 呼叫jdk原始碼AccessController.getContext()獲取安全上線文訪問器
*/
protected AccessControlContext getAccessControlContext();
}
DefaultSingletonBeanRegistry
SingletonBeanRegistry介面的預設實現,繼承自SimpleAliasRegistry類,具有別名、單例Bean註冊管理的相關能力。
具體定義如下:
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
/**
* 標記一個null值,多用於在Concurrent Map中作值存在
*/
protected static final Object NULL_OBJECT = new Object();
/** 子類可訪問的日誌管理器 */
protected final Log logger = LogFactory.getLog(getClass());
/** 下面三個屬性定義了單例初始化過程的"三級快取"
* 在Bean例項化後儲存在三級快取singletonFactories中,
* 當需要時呼叫ObjectFactory.getObject延遲獲取Bean例項,並放入二級快取earlySingletonObjects
* 當Bean初始化結束後,從二級快取earlySingletonObjects移除,放入一級快取singletonObjects中
* 具體獲取順序,singletonObjects->earlySingletonObjects->singletonFactories
**/
/** 一級快取 對映beanName->單例物件*/
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);
/** 二級快取 對映beanName->ObjectFactory*/
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);
/** 三級快取 對映beanName->早期單例物件,即未完整初始化的單例物件*/
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
/** 根據單例Bean的注入順序,儲存單例BeanName */
private final Set<String> registeredSingletons = new LinkedHashSet<String>(64);
/** 儲存處於建立狀態的BeanName */
private final Map<String, Boolean> singletonsCurrentlyInCreation = new ConcurrentHashMap<String, Boolean>(16);
/** 儲存需要過濾建立狀態檢測的BeanName */
private final Map<String, Boolean> inCreationCheckExclusions = new ConcurrentHashMap<String, Boolean>(16);
/** 記錄在嘗試獲取/建立單例過程中遇到的多層捕捉到的異常,最後統一丟擲 */
private Set<Exception> suppressedExceptions;
/** 標誌當前容器是否正在銷燬容器內的所有單例物件 */
private boolean singletonsCurrentlyInDestruction = false;
/** 對映儲存BeanName->實現了Disposable介面bean例項 */
private final Map<String, Object> disposableBeans = new LinkedHashMap<String, Object>();
/** 對映儲存外部BeanName和巢狀Bean集合的對映關係 */
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<String, Set<String>>(16);
/** 對映儲存被依賴的BeanName和依賴BeanName集合的對映關係 */
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<String, Set<String>>(64);
/** 儲存關係和dependentBeanMap相仿對映儲存依賴的BeanName和被依賴BeanName集合的對映關係 */
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<String, Set<String>>(64);
}
具體實現的方法如下所示,主要圍繞上面定義的屬性進行讀寫管理:
SimpleAliasRegistry
一個簡單的別名註冊中心,實現了AliasRegistry介面。
AliasRegistry介面內部定義了4個方法,包括註冊、移除、判斷特定BeanName是否為別名,獲取特定name的所有可能別名(遞迴遍歷過程的所有別名)等。內部定義了唯一的屬性
// 儲存別名->"真名"的對映關係,這裡真名可能為另一個真名的別名
private final Map<String, String> aliasMap = new ConcurrentHashMap<String, String>(16);
SingletonBeanRegistry
定義了單例Bean註冊管理的相關方法,具體定義如下:
public interface SingletonBeanRegistry {
/**
* 註冊指定beanName的單例物件
*/
void registerSingleton(String beanName, Object singletonObject);
/**
* 獲取指定beanName的單例物件
*/
Object getSingleton(String beanName);
/**
* 判斷是否包含指定beanName的單例物件
*/
boolean containsSingleton(String beanName);
/**
* 獲取所有註冊的單例物件beanName
*/
String[] getSingletonNames();
/**
* 獲取註冊的單例個數
*/
int getSingletonCount();
}