SpringApplication.run()的主流程:
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting(); // 启动监听器
ApplicationArguments applicationArguments = new DefaultApplicationArguments(
args);
//创建一个StandardServletEnvironment类型的Environment
ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);
Banner printedBanner = printBanner(environment); //打印banner
// 下一步创建一个AnnotationConfigEmbeddedWebApplicationContext类型的ApplicationContext实例
// 即下面Spring容器加载的核心过程中1的步骤
context = createApplicationContext();
analyzers = new FailureAnalyzers(context);
// 下一步做的工作是加载main类,并把main类注册为名为application的Bean
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);
// 调用Spring底层AbstractApplicationContext刷新容器
refreshContext(context);
afterRefresh(context, applicationArguments);
Spring容器加载的核心过程:
// Prepare the bean factory for use in this context.
// 这一步会加载3个BeanPostProcessor到beanFactory中
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// 这一步对应下面提到的第2步
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
1. ApplicationContext的某个具体的实现类(如AnnotationConfigEmbeddedWebApplicationContext或AnnotationConfigApplicationContext)创建实例时,会调用如下方法:
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
而AnnotatedBeanDefinitionReader的默认构造器会调用registerAnnotationConfigProcessors,接着调用到片段
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
把以下处理器名字:
加到beanFactory的this.beanDefinitionNames列表中,以便在第2步的beanFactory.getBeanNamesForType()能返回beanFactoryPostProcessor的名字。
2. call beanFactoryPostProcessors
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
ConfigurationClassPostProcessor这是个BeanDefinitionRegistryPostProcessor,是在PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()方法执行到下面这个片段的时候创建的:
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
在上面这个片段中, beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)就会创建ConfigurationClassPostProcessor的Bean对象,其中ppName值为org.springframework.context.annotation.internalConfigurationAnnotationProcessor。
再接下去就会执行ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(),这个方法是重中之重,会扫描所配置包下所有的Bean定义,得到beanDefinitionMap。
ConfigurationClassPostProcessor->ConfigurationClassParser parser->ComponentScanAnnotationParser componentScanParser->ClassPathBeanDefinitionScanner scanner, scanner的doScan()方法将返回BeanDefinition的集合。
3. 从第2步得到的所有Bean定义中过滤出BeanPostProcessors,并调用beanFactory.getBean(ppName, BeanPostProcessor.class)方法把这些BeanPostProcessor创建好Bean实例。
greenhouse项目里运行到的第一个需要autowire的Bean是DataSourceInitializerPostProcessor,就是在这里完成Bean创建的。创建好的Bean实例会放到singletonObjects的ConcurrentHashMap中,下次再调用beanFactory.getBean()时直接从这个缓存中获取。
---------------------------------------
greenhouse项目里运行到的第一个需要autowire的Bean是DataSourceInitializerPostProcessor
SpringApplication.run(String ... args)#prepareContext(context, environment, listeners,applicationArguments,printedBanner); 做的工作是加载main类,并把main类注册为名为application的Bean