Spring中Bean注入原始碼分析
theme: smartblue
BeanDefinition和Bean
在Spring中Bean的注入涉及兩部分:
- BeanDefinition
- Bean
兩個物件存在先後順序,先注入BeanDefinition之後才執行Bean物件的注入。
那麼兩者有什麼關聯呢?
BeanDefinition和Bean的關係:可以理解為BeanDefinition是Bean的包裝類,類似Java中類和屬性的關係。
BeanDefinition是對Bean物件的包裝,BeanDefinition中封裝了Bean相關的描述,比如bean物件,bean的單例還是原型、bean的父級、懶載入方式等等。
```java public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
void setScope(@Nullable String scope);
@Nullable
String getScope();
void setLazyInit(boolean lazyInit);
boolean isLazyInit();
}
//bean的原資料 public interface BeanMetadataElement { @Nullable Object getSource(); } ```
在BeanDefinition中繼承了BeanMetadataElement,該類是Bean的原資料,該類中例項化了Bean物件為Object。因此在BeanDefinition中呼叫getSource就可以獲取到Bean物件。
分清楚BeanDefinition和Bean之後再看BeanDefinition的注入,因為只有注入了BeanDefinition才會注入後續的Bean。
BeanDefinition的注入
BeanDefinitionRegistry介面
BeanDefinitin的注入通過介面BeanDefinitionRegistry抽象了各種對BeanDefinition的操作,例如
- BeanDefinitionRegistry#registerBeanDefinition(注入到beanDefinition中)
- BeanDefinitionRegistry#removeBeanDefinition(從beanDefinition容器中移除)
- BeanDefinitionRegistry#getBeanDefinition(獲取BeanDefinition)
```java public interface BeanDefinitionRegistry extends AliasRegistry {
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException;
void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
boolean containsBeanDefinition(String beanName);
String[] getBeanDefinitionNames();
int getBeanDefinitionCount();
boolean isBeanNameInUse(String beanName);
} ```
該介面是操作BeanDefinition的基礎介面,該類是一個介面型別並不是一個抽象類,因此該介面中不會定義任何BeanDefinition的容器,BeanDefinition的容器只在各實現類中定義並使用。任何需要操作BeanDefinition的實現都需要實現該介面。
BeanDefinitionRegistry的實現類
找到操作BeanDefinition的介面就可以通過介面檢視介面的實現類,進而找到BeanDefinition的應用。
BeanDefinition常見的幾個實現類有:
- DefaultListableBeanFactory
- SimpleBeanDefinitionRegistry
SimpleBeanDefinitionRegistry
```java public class SimpleBeanDefinitionRegistry extends SimpleAliasRegistry implements BeanDefinitionRegistry {
/**beanDefinition的容器,通過ConcurrentHashMap實現. */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(64);
//該類的實現方法只是實現了最簡單的beanDefinition的注入,在Java開發環境中並不會使用該實現類
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "'beanName' must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
this.beanDefinitionMap.put(beanName, beanDefinition);
}
} ```
該實現類中只做了最簡單的注入功能,沒有任何的邏輯處理,因此在實際開發過程中Spring並不會使用該類。
DefaultListableBeanFactory
```java public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
//beanDefinition的容器
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
//向BeanFactory中注入BeanDefinition
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
//判斷beanDefinition容器中是否已存在該beanDefinition
if (existingDefinition != null) {
//是否可以覆蓋
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
} else if (existingDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (logger.isInfoEnabled()) {
logger.info("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
existingDefinition + "] with [" + beanDefinition + "]");
}
} else if (!beanDefinition.equals(existingDefinition)) {
if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
} else {
if (logger.isTraceEnabled()) {
logger.trace("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
//覆蓋beanDefinition
this.beanDefinitionMap.put(beanName, beanDefinition);
} else { //容器中不存在該beanDefinition的處理
if (hasBeanCreationStarted()) {
synchronized (this.beanDefinitionMap) { //對beanDefinition加鎖
//注入該beanDefinition
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
if (this.manualSingletonNames.contains(beanName)) {
Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
}
else {
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
} ```
DefaultListableBeanFactory是預設使用的注入BeanDefinition的實現類,可以看到該實現類中對注入BeanDefinition做了很多的邏輯判斷,日常開發啟動容器過程中都會使用該實現類注入BeanDefinition進行後續的Bean注入。
Bean的注入
BeanDefinition注入後後續執行Bean的注入,bean注入的方式也是將bean注入到bean的容器中,因此在Spring中BeanDefinition和Bean都是通過容器化的方式操作的,那麼在Bean的注入中也通過對應的介面定義對Bean的操作,該介面就是SingletonBeanRegistry。
SingletonBeanRegistry介面
該介面實現了對Bean的操作:
- SingletonBeanRegistry#registerSingleton(將bean注入到容器中)
- SingletonBeanRegistry#getSingleton(從容器中獲取bean)
```java public interface SingletonBeanRegistry {
//注入bean
void registerSingleton(String beanName, Object singletonObject);
//獲取bean
@Nullable
Object getSingleton(String beanName);
//是否存在bean
boolean containsSingleton(String beanName);
String[] getSingletonNames();
int getSingletonCount();
Object getSingletonMutex();
} ```
SingletonBeanRegistry的實現類
SingletonBeanRegistry的實現類有多個,分別為:
- AbstractBeanFactory
- DefaultListableBeanFactory
- DefaultSingletonBeanRegistry
- FactoryBeanRegistrySupport
- AbstractAutowireCapableBeanFactory
下面說兩個有代表性的:AbstractBeanFactory和DefaultSingletonBeanRegistry
AbstractBeanFactory
該實現類是一個抽象類,即該類是bean的工廠類,其中主要實現的是可以複用的具體邏輯,該抽象類中包含獲取bean、beanPostProcessor、初始化bean、銷燬bean等對bean的操作抽象類。
```java public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
//獲取bean的方式平時使用ApplicationContext就是最終呼叫該方法
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
@Override
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
@Override
public Object getBean(String name, Object... args) throws BeansException {
return doGetBean(name, null, args, false);
}
public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args)
throws BeansException {
return doGetBean(name, requiredType, args, false);
}
/**
* 從容器中獲取bean的主要邏輯
*/
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
//省略部分程式碼
try {
//先獲取beanDefinition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// 單例模式下獲取bean的方式
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {//原型模式下的bean的獲取
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
//原型模式每次都需要建立bean
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
//省略部分程式碼
return (T) bean;
}
//將實現beanPostProcessor的實現類加入到連結串列中用於對bean的前置或者後置處理
@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
// Remove from old position, if any
this.beanPostProcessors.remove(beanPostProcessor);
// Track whether it is instantiation/destruction aware
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
this.hasInstantiationAwareBeanPostProcessors = true;
}
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
this.hasDestructionAwareBeanPostProcessors = true;
}
// Add to end of list
this.beanPostProcessors.add(beanPostProcessor);
}
//銷燬bean的方法
@Override
public void destroyBean(String beanName, Object beanInstance) {
destroyBean(beanName, beanInstance, getMergedLocalBeanDefinition(beanName));
}
protected void destroyBean(String beanName, Object bean, RootBeanDefinition mbd) {
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), getAccessControlContext()).destroy();
}
} ```
DefaultSingletonBeanRegistry
該實現類通過名字也可以推斷出該實現類是對單例bean的注入,該類中實現了bean的所有容器,平時開發過程中Spring容器啟動就是使用了該實現類中的容器,該實現類是對bean最終注入的實現,涉及的四個容器主要有:
- singletonObjects
- singletonFactories
- earlySingletonObjects
- registeredSingletons
四個容器其中三個的核心作用是解決迴圈依賴,這裡不展開說。
找一條主線梳理下Bean注入的過程,當BeanDefinition注入成功後,後續執行bean的注入,以AbstractAutowireCapableBeanFactory的實現為例,該實現類中會對bean的注入,整個注入的鏈路如下:
- 獲取資源資料:CommonAnnotationBeanPostProcessor#autowireResource
- 通過beanName解析bean:AbstractAutowireCapableBeanFactory#resolveBeanByName
- 呼叫抽象類中獲取bean:AbstractBeanFactory#getBean
- 執行抽象類中獲取bean的核心邏輯:AbstractBeanFactory#doGetBean
- bean不存在時建立bean:AbstractAutowireCapableBeanFactory#createBean
- 獲取單例bean:efaultSingletonBeanRegistry#getSingleton
- 單例bean不存在將類注入到容器中:DefaultSingletonBeanRegistry#addSingleton
```java
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
//單例bean的容器,開發過程中獲取的bean都是從該容器中獲取的:即所謂的一級快取
private final Map
//單例bean的beanFactory的容器:即所謂的三級快取
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
//提前初始化的bean的容器,該容器的bean並沒有任何屬性值只是提前將bean注入到該容器中用於後續的判斷
//即所謂的二級快取
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
//已註冊的單例bean的beanName列表
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
//注入bean的方法
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
Assert.notNull(beanName, "Bean name must not be null");
Assert.notNull(singletonObject, "Singleton object must not be null");
synchronized (this.singletonObjects) {
Object oldObject = this.singletonObjects.get(beanName);
if (oldObject != null) {
throw new IllegalStateException("Could not register object [" + singletonObject +
"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
}
addSingleton(beanName, singletonObject);
}
}
/**
* 將bean注入容器中,操作四個容器主要用於bean的迴圈依賴問題
*/
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
} ```
總結
以上就是對bean注入從原始碼的梳理,該梳理主要從bean注入前的準備(beanDefinition的注入)和bean注入的實現來完成,從整個梳理中學到最多的主要有兩點: - 抽象的思想:在BeanDefinition的實現和Bean的實現邏輯中,都完成高度抽象並且遵循單一原則和高度抽象,程式碼的可擴充套件性和複用性很高,我們作為開發者也可以通過Spring暴露的各種Registry介面實現對Bean的操作。 - 容器化思想:從BeanDefinition和Bean的注入來看,整個的實現思路都是基於容器化思想來實現的,將開發中需要關心的物件都例項化到容器中,開發者在使用時只要從容器中獲取即可,並且獲取bean的方式也很靈活,開發者在使用和擴充套件性上更便利。
對於原始碼的學習自己理解來說並不是背其中的程式碼,而是學習大佬實現程式碼的思想,為什麼可以抽象出擴充套件性這麼高的程式碼,並且從源頭梳理下來都能很輕鬆的按照主線一步一步梳理到目的地,這也是每個開發者需要學習的地方,提高自己程式碼的可讀性和可擴充套件性,能夠掌握面向物件的核心:封裝、繼承、多型。