spring原始碼閱讀(5.1.0版本)——AbstractBeanDefinition
阿新 • • 發佈:2019-01-25
目錄
什麼是AbstractBeanDefinition
AbstractBeanDefinition直接繼承BeanDefiniton,實現了BeanDefinition定義的一系列操作,定義了描述Bean畫像的一系列屬性,在AbstractBeanDefinition的基礎上,Spring衍生出了一系列具有特殊用途的BeanDefinition
原始碼解析
繼承結構
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor implements BeanDefinition, Cloneable
定義的常量
這一些常量會直接影響到spring例項化Bean時的策略,個人理解,其實完全可以不定義這些常量,在使用的時候自行在程式碼中判斷,也可以實現多策略例項化Bean,Spring定義這些常量的原因很簡單,便於維護,讓讀程式碼的人知道每個值的意義,這點在自己寫程式碼時可以注意一下
/** * Constant for the default scope name: {@code ""}, equivalent to singleton * status unless overridden from a parent bean definition (if applicable). */ 預設的SCOPE,預設是單例 public static final String SCOPE_DEFAULT = ""; /** * Constant that indicates no autowiring at all. * @see #setAutowireMode */ 不進行自動裝配 public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO; /** * Constant that indicates autowiring bean properties by name. * @see #setAutowireMode */ 根據Bean的名字進行自動裝配,即autowired屬性的值為byname public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME; /** * Constant that indicates autowiring bean properties by type. * @see #setAutowireMode */ 根據Bean的型別進行自動裝配,呼叫setter函式裝配屬性,即autowired屬性的值為byType public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE; /** * Constant that indicates autowiring a constructor. * @see #setAutowireMode */ 自動裝配建構函式的形參,完成對應屬性的自動裝配,即autowired屬性的值為byConstructor public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR; /** * Constant that indicates determining an appropriate autowire strategy * through introspection of the bean class. * @see #setAutowireMode * @deprecated as of Spring 3.0: If you are using mixed autowiring strategies, * use annotation-based autowiring for clearer demarcation of autowiring needs. */ 通過Bean的class推斷適當的自動裝配策略(autowired=autodetect),如果Bean定義有有參建構函式,則通過自動裝配建構函式形參,完成對應屬性的自動裝配(AUTOWIRE_CONSTRUCTOR),否則,使用setter函式(AUTOWIRE_BY_TYPE) @Deprecated public static final int AUTOWIRE_AUTODETECT = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT; 個人理解:大概是檢查依賴是否合法,在本類中,預設不進行依賴檢查 /** * Constant that indicates no dependency check at all. * @see #setDependencyCheck */ 不進行依賴檢查 public static final int DEPENDENCY_CHECK_NONE = 0; /** * Constant that indicates dependency checking for object references. * @see #setDependencyCheck */ 如果依賴型別為物件引用,則需要檢查 public static final int DEPENDENCY_CHECK_OBJECTS = 1; /** * Constant that indicates dependency checking for "simple" properties. * @see #setDependencyCheck * @see org.springframework.beans.BeanUtils#isSimpleProperty */ 對簡單屬性的依賴進行檢查 public static final int DEPENDENCY_CHECK_SIMPLE = 2; /** * Constant that indicates dependency checking for all properties * (object references as well as "simple" properties). * @see #setDependencyCheck */ 對所有屬性的依賴進行檢查 public static final int DEPENDENCY_CHECK_ALL = 3; /** * Constant that indicates the container should attempt to infer the * {@link #setDestroyMethodName destroy method name} for a bean as opposed to * explicit specification of a method name. The value {@value} is specifically * designed to include characters otherwise illegal in a method name, ensuring * no possibility of collisions with legitimately named methods having the same * name. * <p>Currently, the method names detected during destroy method inference * are "close" and "shutdown", if present on the specific bean class. */ 若Bean未指定銷燬方法,容器應該嘗試推斷Bean的銷燬方法的名字,目前來說,推斷的銷燬方法的名字一般為close或是shutdown (即未指定Bean的銷燬方法,但是內部定義了名為close或是shutdown的方法,則容器推斷其為銷燬方法) public static final String INFER_METHOD = "(inferred)";
屬性
AbstractBeanDefinition定義的屬性基本囊括了Bean例項化需要的所有資訊
Bean的class物件或是類的全限定名 @Nullable private volatile Object beanClass; 預設的scope是單例 @Nullable private String scope = SCOPE_DEFAULT; 預設不為抽象類 private boolean abstractFlag = false; 預設不是懶載入 private boolean lazyInit = false; 預設不進行自動裝配 private int autowireMode = AUTOWIRE_NO; 預設不進行依賴檢查 private int dependencyCheck = DEPENDENCY_CHECK_NONE; 這裡只會存放<bean/>標籤的depends-on屬性或是@DependsOn註解的值 @Nullable private String[] dependsOn; 是自動裝配的候選者,意味著可以自動裝配到其他Bean的某個屬性中 private boolean autowireCandidate = true; 當某個Bean的某個屬性自動裝配有多個候選者(包括自己)時,是否優先注入,即@Primary註解 private boolean primary = false; 這個不是很清楚,查看了這個類的定義,AutowireCandidateQualifier用於解析自動裝配的候選者 private final Map<String, AutowireCandidateQualifier> qualifiers = new LinkedHashMap<>(); 用於初始化Bean的回撥函式,一旦指定,這個方法會覆蓋工廠方法以及建構函式中的元資料 我理解為通過這個函式的邏輯初始化Bean,而不是建構函式或是工廠方法 @Nullable private Supplier<?> instanceSupplier; 是否允許訪問非public方法和屬性,應用於建構函式、工廠方法、init、destroy方法的解析,具體作用是什麼我也不是很清楚 private boolean nonPublicAccessAllowed = true; 指定解析建構函式的模式,是寬鬆還是嚴格(什麼是寬鬆、什麼是嚴格,我沒有找到解釋) private boolean lenientConstructorResolution = true; 工廠類名(注意是String型別,不是Class型別) @Nullable private String factoryBeanName; 工廠方法名(注意是String型別,不是Method型別) @Nullable private String factoryMethodName; 儲存建構函式形參的值 @Nullable private ConstructorArgumentValues constructorArgumentValues; Bean屬性的名稱以及對應的值,這裡不會存放建構函式相關的引數值,只會存放通過setter注入的依賴 @Nullable private MutablePropertyValues propertyValues; 儲存被IOC容器覆蓋的方法的相關資訊(例如replace-method屬性指定的函式) @Nullable private MethodOverrides methodOverrides; init函式的名字 @Nullable private String initMethodName; destory函式的名字 @Nullable private String destroyMethodName; 文件解釋,不知道啥意思,Specify whether or not the configured init method is the default private boolean enforceInitMethod = true; 文件解釋,不知道啥意思,Specify whether or not the configured destroy method is the default private boolean enforceDestroyMethod = true; 是否是合成類(是不是應用自定義的,例如生成AOP代理時,會用到某些輔助類,這些輔助類不是應用自定義的,這個就是合成類) private boolean synthetic = false; Bean的角色,為使用者自定義Bean private int role = BeanDefinition.ROLE_APPLICATION; Bean的描述 @Nullable private String description; @Nullable private Resource resource;
函式就不解析了,基本都是一些set、get操作
總的來說,AbstractBeanDefinition儲存的屬性包括:
- Bean的描述資訊(例如是否是抽象類、是否單例)
- depends-on屬性(String型別,不是Class型別)
- 自動裝配的相關資訊
- init函式、destroy函式的名字(String型別)
- 工廠方法名、工廠類名(String型別,不是Class型別)
- 建構函式形參的值
- 被IOC容器覆蓋的方法
- Bean的屬性以及對應的值(在初始化後會進行填充)
總結
AbstractBeanDefinition定義了一系列描述Bean畫像的屬性,同時實現了BeanDefinition定義的方法,通過這個類,可以窺見Bean的某些預設設定(例如預設為單例),這個類的屬性基本可以在xml配置檔案中找到相應的屬性或是標籤(例如該類的scope屬性對應xml配置檔案中的scope屬性)
本文難免有錯誤,如有錯誤,歡迎指出