Spring5原始碼解析1-從啟動容器開始
@Configuration
@ComponentScan
public class AppConfig {
}
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);
context.close();
}
}
先來看一下AnnotationConfigApplicationContext
類的UML圖,留個印象。
點開AnnotationConfigApplicationContext(AppConfig.class);
方法檢視原始碼:
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) { //呼叫預設無參構造器,裡面有一大堆初始化邏輯 this(); //把傳入的Class進行註冊,Class既可以有@Configuration註解,也可以沒有@Configuration註解 //怎麼註冊? 委託給了 org.springframework.context.annotation.AnnotatedBeanDefinitionReader.register 方法進行註冊 // 傳入Class 生成 BeanDefinition , 然後通過 註冊到 BeanDefinitionRegistry register(annotatedClasses); //重新整理容器上下文 refresh(); }
該構造器允許我們傳入一個或者多個class物件。class物件可以是被@Configuration
標註的,也可以是一個普通的Java 類。
有參構造器呼叫了無參構造器,點開原始碼:
public AnnotationConfigApplicationContext() { //隱式呼叫父類構造器,初始化beanFactory,具體實現類為DefaultListableBeanFactory super(); // 這個程式碼是筆者新增的,方便定位到super方法 //建立 AnnotatedBeanDefinitionReader, //建立時會向傳入的 BeanDefinitionRegistry 中 註冊 註解配置相關的 processors 的 BeanDefinition this.reader = new AnnotatedBeanDefinitionReader(this); this.scanner = new ClassPathBeanDefinitionScanner(this); }
初始化子類時會先初始化父類,會預設呼叫父類無參構造器。AnnotationConfigApplicationContext
繼承了GenericApplicationContext
,在GenericApplicationContext
的無參構造器中,建立了BeanFactory
的具體實現類DefaultListableBeanFactory
。spring中的BeanFactory
就是在這裡被例項化的,並且使用DefaultListableBeanFactory
做的BeanFactory
的預設實現。
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
AnnotationConfigApplicationContext
的構造器中還建立了兩個物件:AnnotatedBeanDefinitionReader
和 ClassPathBeanDefinitionScanner
。
先說scanner
的作用,通過檢視原始碼可以發現,這個scanner
只有在手動呼叫AnnotationConfigApplicationContext
的一些方法的時候才會被使用(通過後面的原始碼探究也可以發現,spring並不是使用這個scanner
來掃描包獲取Bean的)。
建立AnnotatedBeanDefinitionReader
物件。spring在建立reader
的時候把this
當做了引數傳給了構造器。也就是說,reader
物件裡面包含了一個this
物件,也就是AnnotationConfigApplicationContext
物件。AnnotationConfigApplicationContext
實現了BeanDefinitionRegistry
介面。點開this.reader = new AnnotatedBeanDefinitionReader(this);
原始碼:
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
從傳入的BeanDefinitionRegistry
物件,也就是AnnotationConfigApplicationContext
物件中獲取Environment
(共用同一個Environment
),然後又接著呼叫另一個構造器。點開原始碼:
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
//在 BeanDefinitionRegistry 中註冊 註解配置相關的 processors
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
在這個構造器中,執行了一個非常重要的方法AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
,顧名思義,spring通過這個方法註冊瞭解析註解配置相關的處理器。點開原始碼:
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
registerAnnotationConfigProcessors(registry, null);
}
//再點開原始碼
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
//org.springframework.context.annotation.internalConfigurationAnnotationProcessor - ConfigurationClassPostProcessor.class
//這個類非常的重要,它是一個 BeanDefinitionRegistryPostProcessor
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
} catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
- 該方法從傳入的
BeanDefinitionRegistry
物件,也就是AnnotationConfigApplicationContext
物件中獲取到DefaultListableBeanFactory
物件。 - 為獲取的
DefaultListableBeanFactory
物件設定屬性 - 往
DefaultListableBeanFactory
物件中註冊BeanDefinition
,註冊的是一些spring內建的PostProcessor的BeanDefinition
(關於BeanDefinition
的介紹下期在講)。注意,此時只是註冊BeanDefinition
,並沒有例項化bean。預設情況下,執行完該方法後,spring容器中所註冊的BeanDefinition
為:
原始碼學習筆記:https://github.com/shenjianeng/spring-code-study
個人公眾號: