Spring 原始碼學習 - 單例bean的例項化過程
阿新 • • 發佈:2020-06-06
> 本文作者:geek,一個聰明好學的同事
## 1. 簡介
開發中我們常用@Commpont,@Service,@Resource等註解或者配置xml去宣告一個類,使其成為spring容器中的bean,以下我將用從原始碼角度看以AnnotationConfigApplicationContext為例看spring如何把帶有註解的類生成spring中bean。
## 2. 示例程式碼
```java
public class TestContext {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
SingleBean singleBean = context.getBean(SingleBean.class);
System.out.println("<=====>"+singleBean.getTestStr());
}
}
```
```java
@ComponentScan("com.geek")
public class AppConfig {
}
```
```java
@Component
public class SingleBean {
private String testStr = "testStr";
public String getTestStr() {
return testStr;
}
}
```
注意:以上程式碼僅需要引入spring-context依賴即可。
## 3. 原始碼分析
上面的demo在呼叫AnnotationConfigApplicationContext建構函式的時候,AppConfig類會被註冊到AnnotatedBeanDefinitionReader,由這個reader把AppConfig解釋為beanDefination,從而被spring獲取到要例項化的類資訊,以下為bean生產的原始碼及其註釋。(原始碼基於springFramework 5.1.X)
### 3.1 建立入口
單例bean的建立的入口為DefaultListableBeanFactory.java#preInstantiateSingletons,下面原始碼可見建立的bean條件為非抽象,非@LazyInit註解,Scope為singleTon(預設為singleTon)。
```java
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
//所有可能需要去例項化的class(lazy,scope