前文傳送門:
本文內容:
- 在IOC中,是如何通過beanDefition創建出一個bean的?
- 各BeanPostProcessor在這過程中扮演的角色,調用時機?
話不多說,直接正題走起,上圖!
下面是bean創建過程的大致流程圖,本文將以圖中順序進行逐步源碼分析,小伙伴亦可與圖中流程邊對照邊品食
原矢量圖地址:https://www.processon.com/view/link/5f6174431e08531edf3134fb
我們知道,在Spring IOC前段部分有注冊了一系列的BeanPostProcessor,在Bean的創建過程中,就將要使用到他們了,下面我給大家一一列出
-
AutowiredAnnotationBeanPostProcessor:在
new AnnotatedBeanDefinitionReader
時注冊 -
CommonAnnotationBeanPostProcessor: 在
new AnnotatedBeanDefinitionReader
時注冊 -
ApplicationContextAwareProcessor: 在
prepareBeanFactory
時注冊 -
ApplicationListenerDetector: 在
prepareBeanFactory
時注冊 -
ImportAwareBeanPostProcessor: 在配置類后置處理器調用
postProcessBeanFactory
注冊 -
BeanPostProcessorChecker:在
registerBeanPostProcessors
時注冊
以上就是Spring中內置的所有BeanPostProcessor了
同樣,我們先從最開始的入口refresh
開始分析
public void refresh(){
//....省略前面部分
// 實例化剩余的單例bean
finishBeanFactoryInitialization(beanFactory);
}
finishBeanFactoryInitialization
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory){
// 將所有非懶加載的bean加載到容器中
beanFactory.preInstantiateSingletons();
}
循環我們之前注冊的所有beanDefinition,一個個的進行調用getBean注冊到容器中
public void preInstantiateSingletons(){
// 循環所有beanDefinition
for (String beanName : beanNames) {
// 將beanDefinition轉化為RootBeanDefinition
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 不是抽象類並且是單例並且非懶加載
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 是否為工廠bean
if (isFactoryBean(beanName)) {
// 由於是以&開頭獲取bean,這里返回的是一個工廠bean,並且不會調用getObject方法
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
// 判斷是否要立即初始化bean
FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
if (isEagerInit) {
// 以為&開頭的方式再獲取一次,此時會調用FactoryBean的getObject()方法
getBean(beanName);
}
}
}
else {
// 不是FactoryBean,直接使用getBean進行初始化
getBean(beanName);
}
}
}
}
接下來就是Spring的常規操作,調用do開頭的doGetBean
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
以下為doGetBean
中獲取單例bean的邏輯
// 轉化beanName 如果是以&開頭則去除,如果有別名則獲取別名
String beanName = transformedBeanName(name);
// 嘗試從三級緩存中獲取bean
Object sharedInstance = getSingleton(beanName);
// 是否從緩存中獲取到了bean
if (sharedInstance != null && args == null) {
// 如果是工廠類且name不以&開頭,則調用工廠類的getObject()
// 其他情況返回原對象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
getSingleton
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 從單例緩存池中獲取
Object singletonObject = this.singletonObjects.get(beanName);
// 獲取不到,判斷bean是否正在創建
// 如果是正在創建,2種情況 1.多個線程在創建bean 2.發生循環依賴
// 如果是多個線程,則由於同步鎖阻塞於此
// 循環依賴的問題較為復雜,將在下章詳細分析
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 從早期對象緩存池中獲取
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 從三級緩存中獲取單例工廠
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 調用回調方法獲取早期bean
singletonObject = singletonFactory.getObject();
// 將早期對象放到二級緩存,移除三級緩存
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
getObjectForBeanInstance
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// 判斷name是否以&開頭,是則直接返回該FactoryBean
/*public static boolean isFactoryDereference(@Nullable String name) {
return (name != null && name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
}*/
if (BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
// 不是工廠bean直接返回原對象
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
// 嘗試從緩存中獲取,保證多次從工廠bean獲取的bean是同一個bean
object = getCachedObjectForFactoryBean(beanName);
if (object == null) {
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
boolean synthetic = (mbd != null && mbd.isSynthetic());
// 從FactoryBean獲取對象
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
getObjectFromFactoryBean的代碼摘取片段
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess){
// 獲取bean,調用factoryBean的getObject()
object = doGetObjectFromFactoryBean(factory, beanName);
}
private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName){
object = factory.getObject();
}
以上為從緩存中獲取到bean,處理FactoryBean的邏輯,接下來我們看看實際創建bean的過程
以下為續接上面doGetBean
中未從緩存中獲取到bean的邏輯
// 如果有被@DependsOn標記,先創建DependsOn的bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
registerDependentBean(dep, beanName);
getBean(dep);
}
}
// 單例bean
if (mbd.isSingleton()) {
// 開始創建bean
sharedInstance = getSingleton(beanName, () -> {
// 真正創建bean
return createBean(beanName, mbd, args);
});
// 如果是工廠類且name不以&開頭,則調用工廠類的getObject()
// 其他情況返回原對象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
getSingleton,此方法為重載方法,與從緩存中獲取bean並非同一個
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
// 開始創建bean時加鎖,注意這個鎖的同步對象與從緩存中獲取時鎖的同步對象相同
synchronized (this.singletonObjects) {
// 再次從緩存中獲取,有直接返回,出現有的情況
// 1.線程一正在創建A實例,線程二嘗試獲取,被同步鎖阻塞
// 2.線程一創建完畢,線程二進入同步代碼塊,從緩存中獲取直接返回
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 標記正在創建中
beforeSingletonCreation(beanName);
boolean newSingleton = false;
try {
// 調用回調函數獲取到bean
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
finally {
// 清理狀態
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 將創建的bean添加到單例緩存池中,並移除二三級緩存
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
createBean,終於開始創建bean了~
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args){
// 第一次調用bean后置處理器,在bean實例化之前的進行處理
// Spring內置的后置處理器中,無相關實現
// 可使用自定義的后置處理器在這里進行中止bean的創建過程操作
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
// 如果自定義的后置處理器返回了bean,則直接return,bean的創建過程於此中斷
return bean;
}
// 進行創建bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
}
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args){
// 實例化bean 第二次調用bean后置處理器,用於獲取bean的有參構造器
instanceWrapper = createBeanInstance(beanName, mbd, args);
// 第三次 處理beanDefinition的元數據信息
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
// 是否允許暴露早期對象
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
// 第四次 用於獲取早期對象時的處理
// 將獲取早期對象的回調方法放到三級緩存中
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
// 第五、六次,填充屬性 可使用的方式 byName byType @Resource @Value @Autowired @Inject
populateBean(beanName, mbd, instanceWrapper);
// 第七、八次,初始化
exposedObject = initializeBean(beanName, exposedObject, mbd);
// 第九次 判斷bean是否有銷毀方法,有則將bean注冊到銷毀集合中,用於容器關閉時使用
registerDisposableBeanIfNecessary(beanName, bean, mbd);
// 返回創建好的bean
return exposedObject;
}
你以為這就結束了?
接下來我們就來看看這里后置處理器到底做了什么吧
由於第一次調用並未有任何處理,我們從第二次調用開始分析
createBeanInstance
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args){
// 獲取beanClass
Class<?> beanClass = resolveBeanClass(mbd, beanName);
// 使用AutowiredAnnotationBeanPostProcessor進行構造器推斷,找到所有的有參構造器
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
// 實例化bean,並根據參數自動裝配
return autowireConstructor(beanName, mbd, ctors, args);
}
// 調用無參的構造方法實例化
return instantiateBean(beanName, mbd);
}
determineConstructorsFromBeanPostProcessors
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
throws BeansException {
if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
// 只有AutowiredAnnotationBeanPostProcessor進行了實現,其他的都返回null
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
// 確認候選的構造器
Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
return ctors;
}
}
}
}
return null;
}
AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName){
// 獲取到所有的構造方法
rawCandidates = beanClass.getDeclaredConstructors();
for (Constructor<?> candidate : rawCandidates) {
// 是否帶有@Autowired注解
MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
if (ann != null) {
// 是否必須
boolean required = determineRequiredStatus(ann);
candidates.add(candidate);
}
else if (candidate.getParameterCount() == 0) {
// 無參構造器
defaultConstructor = candidate;
}
}
// 候選的構造器不為空
if (!candidates.isEmpty()) {
// 候選的構造器不為空而requiredConstructor為空表示有@Autowired標識的構造器
// 但是required=false
if (requiredConstructor == null) {
if (defaultConstructor != null) {
// 將無參構造器也加入到候選構造器集合中
candidates.add(defaultConstructor);
}
}
// 將集合中的構造器轉化為數組
candidateConstructors = candidates.toArray(new Constructor<?>[0]);
}
// 候選的構造器為空,但有一個有參構造器,則使用有參構造器作為候選的構造器
else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
}
// 返回候選構造器數組
return (candidateConstructors.length > 0 ? candidateConstructors : null);
}
autowireConstructor 實例化並自動裝配,摘取代碼片段
protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
for (Constructor<?> candidate : candidates) {
// 獲取參數的類型
Class<?>[] paramTypes = candidate.getParameterTypes();
// 獲取依賴的bean
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames..);
// 調用instantiate方法進行實例化bean
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
}
}
以上便是bean的實例化過程
applyMergedBeanDefinitionPostProcessors
第三次主要是將標識了需要自動裝配注解的屬性或方法解析出來,包含的注解主要有 @Resource @Autowired @Value @Inject @PostConstruct @PreDestroy
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
// CommonAnnotationBeanPostProcessor解析@PostConstruct @PreDestroy @Resource
// AutowiredAnnotationBeanPostProcessor 解析@Autowired @Value @Inject
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
CommonAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
// 父類為InitDestroyAnnotationBeanPostProcessor
// 尋找@PostConstruct @PreDestroy注解的方法
// 用於bean的生命周期中初始化前的處理邏輯
super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
// 尋找@Resource注解標識的屬性或方法元數據
// 將這些元數據保存到緩存中,用於在屬性裝配階段使用
InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
// 檢查是否有重復的元數據,去重處理,如一個屬性上既有@Autowired注解,又有@Resource注解
// 只使用一種方式進行注入,由於@Resource先進行解析,所以會選擇@Resource的方式
metadata.checkConfigMembers(beanDefinition);
}
InitDestroyAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
// 尋找PostConstruct @PreDestroy注解的方法
LifecycleMetadata metadata = findLifecycleMetadata(beanType);
// 去重處理
metadata.checkConfigMembers(beanDefinition);
}
所有的后置處理器的過程是相似的,這里取CommonAnnotationBeanPostProcessor進行分析
我們先來看看尋找元數據的過程
private InjectionMetadata findResourceMetadata(String beanName, final Class<?> clazz, @Nullable PropertyValues pvs) {
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// 從緩存中獲取
// 調用postProcessMergedBeanDefinition方法時將元數據解析放入緩存
// 調用postProcessProperties方法時將元數據取出
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
// 創建元數據,尋找@Resouce標識的屬性或方法
metadata = buildResourceMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
buildResourceMetadata
private InjectionMetadata buildResourceMetadata(final Class<?> clazz){
// 判斷是否為候選的class,不是則返回默認的空元數據
// resourceAnnotationTypes為Annotation集合,里面包含了@Resource @EJB @WebServiceRef
// 我們一般常用的只是@Resource
if (!AnnotationUtils.isCandidateClass(clazz, resourceAnnotationTypes)) {
return InjectionMetadata.EMPTY;
}
do {
// 循環所有的屬性,判斷屬性是否存在WebServiceRef、EJB、Resource注解,有則構建元數據
// doWithLocalFields中就是將targetClass的所有field取出進行循環
ReflectionUtils.doWithLocalFields(targetClass, field -> {
if (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) {
currElements.add(new WebServiceRefElement(field, field, null));
}
else if (ejbClass != null && field.isAnnotationPresent(ejbClass)) {
currElements.add(new EjbRefElement(field, field, null));
}
// 是否存在@Resource注解
else if (field.isAnnotationPresent(Resource.class)) {
if (!this.ignoredResourceTypes.contains(field.getType().getName())) {
currElements.add(new ResourceElement(field, field, null));
}
}
});
// 與上一步相似,判斷方法上是否存在這些注解
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
//......省略
});
// 獲取父類
targetClass = targetClass.getSuperclass();
}
// 父類不是Object則繼續循環父類中的屬性和方法
while (targetClass != null && targetClass != Object.class);
// 將構建好的元數據封裝到InjectionMetadata中返回
return InjectionMetadata.forElements(elements, clazz);
}
現在我們再來看看去重處理的過程
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
Set<InjectedElement> checkedElements = new LinkedHashSet<>(this.injectedElements.size());
for (InjectedElement element : this.injectedElements) {
Member member = element.getMember();
// 檢查該beanDefinition的externallyManagedConfigMembers集合中是否已經包含該成員(屬性或者方法)
if (!beanDefinition.isExternallyManagedConfigMember(member)) {
// 不包含則將該成員注冊
beanDefinition.registerExternallyManagedConfigMember(member);
// 加入到已檢查的集合
checkedElements.add(element);
}
}
this.checkedElements = checkedElements;
}
由於第四次,用於獲取早期對象時的處理的調用,在Spring的內置處理器中也沒有相應的實現,跳過
這一步和第一步一樣,在AOP時將會用到,我們放到下章分析
緊接着就是填充屬性的步驟了
populateBean
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// 在這里可進行中止填充屬性操作,實現InstantiationAwareBeanPostProcessor接口
// 並postProcessAfterInstantiation返回false,則直接返回,不會再往下執行
// Spring內中的后置處理器皆返回的true
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
// 獲得自動裝配的類型,默認為0,
// 這里只有xml配置,ImportBeanDefinitionRegistrar,BeanFactoryPostProcessor可進行改變
// Spring整合Mybatis中,將Mapper的自動裝配類型改成了BY_TYPE,
// 於是在Mapper得以在這里被填充SqlSessionTemplate,SqlSessionFactory屬性
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
// 獲取到依賴的bean並放到newPvs中
autowireByType(beanName, mbd, bw, newPvs);
}
// 將新的屬性列表賦給舊的引用
pvs = newPvs;
}
}
autowireByName 和 autowireByType差不多,autowireByType更為復雜一些,這里只分析autowireByType的處理過程
protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
// 查詢非簡單(Java內置 基本類型,String,Date等)的屬性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
// 循環所有屬性名
for (String propertyName : propertyNames) {
// 獲取方法參數
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// 構建一個依賴描述符
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
// 獲取依賴的bean
// resolveDependency方法中調用了doResolveDependency,該方法我們在下一步的后置處理器調用中分析
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
// 將bean放置到屬性集合中
if (autowiredArgument != null) {
pvs.add(propertyName, autowiredArgument);
}
}
}
現在,回到填充屬性的過程
該第六次調用后置處理器了,這一次主要對屬性和方法進行自動裝配
// CommonAnnotationBeanPostProcessor 處理@Resouce注解的裝配
// AutowiredAnnotationBeanPostProcessor 處理@Autowired @Value @Inject注解的裝配
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 處理自動裝配,將依賴的屬性裝配到bean中
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
// ...省略已被廢棄的代碼...
pvs = pvsToUse;
}
}
這一步的邏輯也是差不多,由於AutowiredAnnotationBeanPostProcessor復雜一些,我們取AutowiredAnnotationBeanPostProcessor中的邏輯進行分析
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// 取出之前postProcessMergedBeanDefinition時解析好的元數據
// @Autowired @Value @Inject 標識的屬性或方法
// findAutowiringMetadata這里有沒有和第四步中的很像呢~
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
// 進行自動裝配
metadata.inject(bean, beanName, pvs);
return pvs;
}
findAutowiringMetadata,看看和第四步有多像吧~
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// 從緩存中取出
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
// 構建元數據,找到@Autowird @Value @Inject 標識的屬性或方法進行構建
metadata = buildAutowiringMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
自動裝配過程
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) {
// 取出之前去重過的元數據列表
Collection<InjectedElement> checkedElements = this.checkedElements;
if (!elementsToIterate.isEmpty()) {
for (InjectedElement element : elementsToIterate) {
// 進行屬性或方法裝配
element.inject(target, beanName, pvs);
}
}
}
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs){
// 強轉成Field
Field field = (Field) this.member;
// 創建一個依賴描述符
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
// 獲取到依賴的bean
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
if (value != null) {
ReflectionUtils.makeAccessible(field);
// 將獲取到的依賴bean利用反射裝配到屬性中
field.set(bean, value);
}
}
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) {
// 獲取bean
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
return result;
}
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter){
// 解析@Value注解
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
}
// 根據類型尋找是否有匹配的beanDefinition
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
// 為空則判斷是否必須
if (isRequired(descriptor)) {
// 必須則拋出NoSuchBeanDefinitionException異常
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
// 如果根據類型匹配出來的候選bean不止一個,則需要確認是哪一個
if (matchingBeans.size() > 1) {
// 確認出真正需要依賴的
// 先判斷是否有@Primary注解的
// 沒有再判斷是否有實現了Priority注解的,取值最小的
// 沒有最后使用屬性名進行匹配
// 匹配不到則返回null
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
// 這里進行確認是否必須,必須則拋出異常
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
}
else {
return null;
}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
if (instanceCandidate instanceof Class) {
// 調用getBean方法
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
return result;
}
getBean方法
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory) {
return beanFactory.getBean(beanName);
}
以上就是自動裝配的過程,再次回到填充屬性的方法,進行小小的收尾
// 如果不是xml byName byType 方式,其他方式pvs皆是空值
if (pvs != null) {
// 調用set方法賦值
applyPropertyValues(beanName, mbd, bw, pvs);
}
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
// 使用反射給屬性賦值
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
填充屬性過程,over~
初始化過程
initializeBean
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd){
// 如果bean實現了BeanNameAware,BeanClassLoaderAware,BeanFactoryAware接口
// 則進行回調相應的方法
invokeAwareMethods(beanName, bean);
// 第七次 在bean的初始化前進行處理
// 調用@PostConstruct注解的方法,Aware接口的回調方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
// 調用初始化方法
// 如果bean實現了InitializingBean接口,則調用afterPropertiesSet方法
// 如果bean還實現了自定義的初始化方法,也進行調用
// 先afterPropertiesSet,再自定義
invokeInitMethods(beanName, wrappedBean, mbd);
// 第八次 處理初始化后的bean
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
以上為初始化中的大概流程,接下來我們一個個分析
首先是invokeAwareMethods
private void invokeAwareMethods(String beanName, Object bean) {
// 以下過程一目了然,就不過多分析了
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
applyBeanPostProcessorsBeforeInitialization
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName){
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// ImportAwareBeanPostProcessor處理ImportAware接口
// InitDestroyAnnotationBeanPostProcessor處理@PostContrust注解
// ApplicationContextAwareProcessor處理一系列Aware接口的回調方法
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
InitDestroyAnnotationBeanPostProcessor
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 取出在第四步解析@PostContrust @PreDestroy得到的元數據
LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
// 調用init方法(@PostConstruct標識的)
metadata.invokeInitMethods(bean, beanName);
return bean;
}
public void invokeInitMethods(Object target, String beanName) throws Throwable {
// 只取init的元數據(還有destroy的)
Collection<LifecycleElement> checkedInitMethods = this.checkedInitMethods;
if (!initMethodsToIterate.isEmpty()) {
for (LifecycleElement element : initMethodsToIterate) {
element.invoke(target);
}
}
}
public void invoke(Object target) throws Throwable {
ReflectionUtils.makeAccessible(this.method);
// 直接反射調用
this.method.invoke(target, (Object[]) null);
}
ApplicationContextAwareProcessor的過程和invokeAwareMethods的過程類似,這里就不分析了
invokeInitMethods
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd){
// 如果實現了InitializingBean接口,調用afterPropertiesSet方法
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
((InitializingBean) bean).afterPropertiesSet();
}
if (mbd != null && bean.getClass() != NullBean.class) {
// 調用自定義的初始化方法
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
// 自定義init方法主要在@Bean注解進行聲明,取出beanDefinition中的initMethod調用就好了
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
applyBeanPostProcessorsAfterInitialization
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// Spring內置后置處理器中,只有ApplicationListenerDetector有處理邏輯
// ApplicationListenerDetector會將實現了ApplicationListener接口的bean添加到事件監聽器列表中
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
public Object postProcessAfterInitialization(Object bean, String beanName){
if (bean instanceof ApplicationListener) {
// 將bean添加到事件監聽器列表中
this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
}
}
以上,bean初始化完畢!
伴隨着bean初始化完畢,bean就算創建完成了,本文也到此結束啦,有問題的小伙伴歡迎在下方留言喲~
下文預告:Spring源碼分析之循環依賴
Spring 源碼系列
- Spring源碼分析之 IOC 容器預啟動流程(已完結)
- Spring源碼分析之BeanFactory體系結構(已完結)
- Spring源碼分析之BeanFactoryPostProcessor調用過程(已完結)
- Spring源碼分析之Bean的創建過程(已完結)
- Spring源碼分析之什么是循環依賴及解決方案
- Spring源碼分析之AOP從解析到調用
- Spring源碼分析之事務管理(上),事物管理是spring作為容器的一個特點,總結一下他的基本實現與原理吧
- Spring源碼分析之事務管理(下) ,關於他的底層事物隔離與事物傳播原理,重點分析一下
Spring Mvc 源碼系列
- SpringMvc體系結構
- SpringMvc源碼分析之Handler解析過程
- SpringMvc源碼分析之請求鏈過程
Mybatis 源碼系列
暫定
追更,可關注我,近期有時間就文章全寫完,分享純粹為了樂趣,也有一種成就感吧,筆者這篇文章先就到這