從啟動(dòng)容器開(kāi)始
最簡(jiǎn)單的啟動(dòng)spring的代碼如下:
@Configuration
@ComponentScan
public class AppConfig {
}
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);
context.close();
}
}
先來(lái)看一下AnnotationConfigApplicationContext
類的UML圖锐借,留個(gè)印象。
點(diǎn)開(kāi)AnnotationConfigApplicationContext(AppConfig.class);
方法查看源碼:
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
//調(diào)用默認(rèn)無(wú)參構(gòu)造器,里面有一大堆初始化邏輯
this();
//把傳入的Class進(jìn)行注冊(cè),Class既可以有@Configuration注解,也可以沒(méi)有@Configuration注解
//怎么注冊(cè)? 委托給了 org.springframework.context.annotation.AnnotatedBeanDefinitionReader.register 方法進(jìn)行注冊(cè)
// 傳入Class 生成 BeanDefinition , 然后通過(guò) 注冊(cè)到 BeanDefinitionRegistry
register(annotatedClasses);
//刷新容器上下文
refresh();
}
該構(gòu)造器允許我們傳入一個(gè)或者多個(gè)class對(duì)象绒尊。class對(duì)象可以是被@Configuration
標(biāo)注的音五,也可以是一個(gè)普通的Java 類。
有參構(gòu)造器調(diào)用了無(wú)參構(gòu)造器然眼,點(diǎn)開(kāi)源碼:
public AnnotationConfigApplicationContext() {
//隱式調(diào)用父類構(gòu)造器,初始化beanFactory,具體實(shí)現(xiàn)類為DefaultListableBeanFactory
super(); // 這個(gè)代碼是筆者添加的讳推,方便定位到super方法
//創(chuàng)建 AnnotatedBeanDefinitionReader,
//創(chuàng)建時(shí)會(huì)向傳入的 BeanDefinitionRegistry 中 注冊(cè) 注解配置相關(guān)的 processors 的 BeanDefinition
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
初始化子類時(shí)會(huì)先初始化父類顶籽,會(huì)默認(rèn)調(diào)用父類無(wú)參構(gòu)造器。AnnotationConfigApplicationContext
繼承了GenericApplicationContext
银觅,在GenericApplicationContext
的無(wú)參構(gòu)造器中礼饱,創(chuàng)建了BeanFactory
的具體實(shí)現(xiàn)類DefaultListableBeanFactory
。spring中的BeanFactory
就是在這里被實(shí)例化的设拟,并且使用DefaultListableBeanFactory
做的BeanFactory
的默認(rèn)實(shí)現(xiàn)慨仿。
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
AnnotationConfigApplicationContext
的構(gòu)造器中還創(chuàng)建了兩個(gè)對(duì)象:AnnotatedBeanDefinitionReader
和 ClassPathBeanDefinitionScanner
。
先說(shuō)scanner
的作用纳胧,通過(guò)查看源碼可以發(fā)現(xiàn)镰吆,這個(gè)scanner
只有在手動(dòng)調(diào)用AnnotationConfigApplicationContext
的一些方法的時(shí)候才會(huì)被使用(通過(guò)后面的源碼探究也可以發(fā)現(xiàn),spring并不是使用這個(gè)scanner
來(lái)掃描包獲取Bean的)跑慕。
創(chuàng)建AnnotatedBeanDefinitionReader
對(duì)象万皿。spring在創(chuàng)建reader
的時(shí)候把this
當(dāng)做了參數(shù)傳給了構(gòu)造器。也就是說(shuō)核行,reader
對(duì)象里面包含了一個(gè)this
對(duì)象牢硅,也就是AnnotationConfigApplicationContext
對(duì)象。AnnotationConfigApplicationContext
實(shí)現(xiàn)了BeanDefinitionRegistry
接口芝雪。點(diǎn)開(kāi)this.reader = new AnnotatedBeanDefinitionReader(this);
源碼:
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
從傳入的BeanDefinitionRegistry
對(duì)象减余,也就是AnnotationConfigApplicationContext
對(duì)象中獲取Environment
(共用同一個(gè)Environment
),然后又接著調(diào)用另一個(gè)構(gòu)造器惩系。點(diǎn)開(kāi)源碼:
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 中注冊(cè) 注解配置相關(guān)的 processors
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
在這個(gè)構(gòu)造器中位岔,執(zhí)行了一個(gè)非常重要的方法AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
如筛,顧名思義,spring通過(guò)這個(gè)方法注冊(cè)了解析注解配置相關(guān)的處理器抒抬。點(diǎn)開(kāi)源碼:
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
registerAnnotationConfigProcessors(registry, null);
}
//再點(diǎn)開(kāi)源碼
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
//這個(gè)類非常的重要,它是一個(gè) 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
對(duì)象杨刨,也就是AnnotationConfigApplicationContext
對(duì)象中獲取到DefaultListableBeanFactory
對(duì)象。 - 為獲取的
DefaultListableBeanFactory
對(duì)象設(shè)置屬性 - 往
DefaultListableBeanFactory
對(duì)象中注冊(cè)BeanDefinition
擦剑,注冊(cè)的是一些spring內(nèi)置的PostProcessor的BeanDefinition
(關(guān)于BeanDefinition
的介紹下期在講)妖胀。注意,此時(shí)只是注冊(cè)BeanDefinition
惠勒,并沒(méi)有實(shí)例化bean赚抡。默認(rèn)情況下,執(zhí)行完該方法后纠屋,spring容器中所注冊(cè)的BeanDefinition
為:
源碼學(xué)習(xí)筆記:https://github.com/shenjianeng/spring-code-study