Springbootロードbeanプロセス探索
14558 ワード
Springbootは一般的に次のmainメソッドでプロジェクトを開始します.
ソースコードを表示すると、ロードされた主な論理が
ConfigurableApplicationContext org. springframework. boot. SpringApplication.run(String...args)この方法の中で
具体的なロジックは次のとおりです.
次に「beanをコンテナcontextにロードする」というこの方法prepareContext(context,environment,listeners,applicationArguments,printedBanner)の論理に重点を置く
メソッドのコード実装ロジックは次のとおりです.
loadメソッドの具体的な実装:
以下org.springframework.boot.BeanDefinitionLoaderのloanメソッド実装ロジック:
つまり、
クラスのプログラミング登録を宣言する便利なアダプタです.これはClassPathBeanDefinitionsCannerの代替方法であり、宣言クラス解析を適用しますが、明示的に登録されているクラスに限定されます.
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
ソースコードを表示すると、ロードされた主な論理が
ConfigurableApplicationContext org. springframework. boot. SpringApplication.run(String...args)この方法の中で
具体的なロジックは次のとおりです.
/**
* Run the Spring application, creating and refreshing a new
* {@link ApplicationContext}.
* @param args the application arguments (usually passed from a Java main method)
* @return a running {@link ApplicationContext}
*/
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection exceptionReporters = new ArrayList<>();
configureHeadlessProperty();
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(
args);
ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);
configureIgnoreBeanInfo(environment);
Banner printedBanner = printBanner(environment);
//1.
context = createApplicationContext();
exceptionReporters = getSpringFactoriesInstances(
SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
//2. bean context
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);
refreshContext(context);
afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass)
.logStarted(getApplicationLog(), stopWatch);
}
listeners.started(context);
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
try {
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, null);
throw new IllegalStateException(ex);
}
return context;
}
次に「beanをコンテナcontextにロードする」というこの方法prepareContext(context,environment,listeners,applicationArguments,printedBanner)の論理に重点を置く
メソッドのコード実装ロジックは次のとおりです.
private void prepareContext(ConfigurableApplicationContext context,
ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments, Banner printedBanner) {
context.setEnvironment(environment);
postProcessApplicationContext(context);
applyInitializers(context);
listeners.contextPrepared(context);
if (this.logStartupInfo) {
logStartupInfo(context.getParent() == null);
logStartupProfileInfo(context);
}
// Add boot specific singleton beans
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
if (printedBanner != null) {
beanFactory.registerSingleton("springBootBanner", printedBanner);
}
if (beanFactory instanceof DefaultListableBeanFactory) {
((DefaultListableBeanFactory) beanFactory)
.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
// Load the sources , @SpringBootApplication DemoApplication
Set
loadメソッドの具体的な実装:
/**
* Load beans into the application context.
* @param context the context to load beans into
* @param sources the sources to load
*/
protected void load(ApplicationContext context, Object[] sources) {
if (logger.isDebugEnabled()) {
logger.debug(
"Loading source " + StringUtils.arrayToCommaDelimitedString(sources));
}
// BeanDefinationLoader org.springframework.boot.BeanDefinitionLoader, springboot beanDefination ,
BeanDefinitionLoader loader = createBeanDefinitionLoader(
getBeanDefinitionRegistry(context), sources);
if (this.beanNameGenerator != null) {
loader.setBeanNameGenerator(this.beanNameGenerator);
}
if (this.resourceLoader != null) {
loader.setResourceLoader(this.resourceLoader);
}
if (this.environment != null) {
loader.setEnvironment(this.environment);
}
//org.springframework.boot.BeanDefinitionLoader beanDefination spring BeanDefinationRegistry
loader.load();
}
以下org.springframework.boot.BeanDefinitionLoaderのloanメソッド実装ロジック:
private int load(Class> source) {
if (isGroovyPresent()
&& GroovyBeanDefinitionSource.class.isAssignableFrom(source)) {
// Any GroovyLoaders added in beans{} DSL can contribute beans here
GroovyBeanDefinitionSource loader = BeanUtils.instantiateClass(source,
GroovyBeanDefinitionSource.class);
load(loader);
}
if (isComponent(source)) {
// org.springframework.context.annotation.AnnotatedBeanDefinitionReader.AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry)
this.annotatedReader.register(source);
return 1;
}
return 0;
}
org.springframework.context.annotation.AnnotatedBeanDefinitionReader ?
AnnotatedBeanDefinitionReader :
/**
* Convenient adapter for programmatic registration of annotated bean classes.
* This is an alternative to {@link ClassPathBeanDefinitionScanner}, applying
* the same resolution of annotations but for explicitly registered classes only.
*
* @author Juergen Hoeller
* @author Chris Beams
* @author Sam Brannen
* @author Phillip Webb
* @since 3.0
* @see AnnotationConfigApplicationContext#register
*/
public class AnnotatedBeanDefinitionReader
つまり、
クラスのプログラミング登録を宣言する便利なアダプタです.これはClassPathBeanDefinitionsCannerの代替方法であり、宣言クラス解析を適用しますが、明示的に登録されているクラスに限定されます.