256 lines
8.7 KiB
Markdown
256 lines
8.7 KiB
Markdown
## 启动简单流程
|
||
|
||
1. allowing for further customization
|
||
1. 创建一个依赖启动类的实例ApplicationContext
|
||
2. 注册一个CommandLinePropertySource用来解析参数,并应用在容器中
|
||
3. 刷新应用上下文,加载单例。
|
||
4. 处理CommandLineRunner
|
||
|
||
一次实例化类
|
||
|
||
1. ApplicationContextInitializer
|
||
2. ApplicationListener
|
||
3. SpringApplicationRunListener
|
||
|
||
# 启动
|
||
|
||
```java
|
||
public static void main(String[] args) {
|
||
SpringApplication.run(PlantformApplication.class, args);
|
||
}
|
||
```
|
||
|
||
# 运行
|
||
|
||
```java
|
||
/**
|
||
* Static helper that can be used to run a {@link SpringApplication} from the
|
||
* specified source using default settings.
|
||
* @param primarySource the primary source to load
|
||
* @param args the application arguments (usually passed from a Java main method)
|
||
* @return the running {@link ApplicationContext}
|
||
*/
|
||
public static ConfigurableApplicationContext run(Class<?> primarySource,
|
||
String... args) {
|
||
return run(new Class<?>[] { primarySource }, args);
|
||
}
|
||
```
|
||
|
||
```java
|
||
/**
|
||
* Static helper that can be used to run a {@link SpringApplication} from the
|
||
* specified sources using default settings and user supplied arguments.
|
||
* @param primarySources the primary sources to load
|
||
* @param args the application arguments (usually passed from a Java main method)
|
||
* @return the running {@link ApplicationContext}
|
||
*/
|
||
public static ConfigurableApplicationContext run(Class<?>[] primarySources,
|
||
String[] args) {
|
||
return new SpringApplication(primarySources).run(args);
|
||
}
|
||
```
|
||
|
||
## 创建对象
|
||
|
||
```java
|
||
public SpringApplication(Class<?>... primarySources) {
|
||
this(null, primarySources);
|
||
}
|
||
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
|
||
this.resourceLoader = resourceLoader;
|
||
Assert.notNull(primarySources, "PrimarySources must not be null");
|
||
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
|
||
this.webApplicationType = WebApplicationType.deduceFromClasspath();
|
||
setInitializers((Collection) getSpringFactoriesInstances(
|
||
ApplicationContextInitializer.class));
|
||
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
|
||
this.mainApplicationClass = deduceMainApplicationClass();
|
||
}
|
||
|
||
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type,
|
||
Class<?>[] parameterTypes, Object... args) {
|
||
ClassLoader classLoader = getClassLoader();
|
||
// Use names and ensure unique to protect against duplicates
|
||
Set<String> names = new LinkedHashSet<>(
|
||
SpringFactoriesLoader.loadFactoryNames(type, classLoader));
|
||
List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
|
||
classLoader, args, names);
|
||
AnnotationAwareOrderComparator.sort(instances);
|
||
return instances;
|
||
}
|
||
```
|
||
|
||
## run
|
||
|
||
```java
|
||
public ConfigurableApplicationContext run(String... args) {
|
||
StopWatch stopWatch = new StopWatch();
|
||
stopWatch.start();
|
||
ConfigurableApplicationContext context = null;
|
||
Collection<SpringBootExceptionReporter> 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);
|
||
context = createApplicationContext();
|
||
exceptionReporters = getSpringFactoriesInstances(
|
||
SpringBootExceptionReporter.class,
|
||
new Class[] { ConfigurableApplicationContext.class }, 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;
|
||
}
|
||
|
||
private SpringApplicationRunListeners getRunListeners(String[] args) {
|
||
Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
|
||
return new SpringApplicationRunListeners(logger, getSpringFactoriesInstances(
|
||
SpringApplicationRunListener.class, types, this, args));
|
||
}
|
||
private ConfigurableEnvironment prepareEnvironment(
|
||
SpringApplicationRunListeners listeners,
|
||
ApplicationArguments applicationArguments) {
|
||
// Create and configure the environment
|
||
ConfigurableEnvironment environment = getOrCreateEnvironment();
|
||
configureEnvironment(environment, applicationArguments.getSourceArgs());
|
||
listeners.environmentPrepared(environment);
|
||
bindToSpringApplication(environment);
|
||
if (!this.isCustomEnvironment) {
|
||
environment = new EnvironmentConverter(getClassLoader())
|
||
.convertEnvironmentIfNecessary(environment, deduceEnvironmentClass());
|
||
}
|
||
ConfigurationPropertySources.attach(environment);
|
||
return environment;
|
||
}
|
||
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type,
|
||
Class<?>[] parameterTypes, Object... args) {
|
||
ClassLoader classLoader = getClassLoader();
|
||
// Use names and ensure unique to protect against duplicates
|
||
Set<String> names = new LinkedHashSet<>(
|
||
SpringFactoriesLoader.loadFactoryNames(type, classLoader));
|
||
List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
|
||
classLoader, args, names);
|
||
AnnotationAwareOrderComparator.sort(instances);
|
||
return instances;
|
||
}
|
||
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
|
||
Set<Object> sources = getAllSources();
|
||
Assert.notEmpty(sources, "Sources must not be empty");
|
||
load(context, sources.toArray(new Object[0]));
|
||
listeners.contextLoaded(context);
|
||
}
|
||
|
||
public void refresh() throws BeansException, IllegalStateException {
|
||
synchronized (this.startupShutdownMonitor) {
|
||
// Prepare this context for refreshing.
|
||
prepareRefresh();
|
||
|
||
// Tell the subclass to refresh the internal bean factory.
|
||
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
|
||
|
||
// Prepare the bean factory for use in this context.
|
||
prepareBeanFactory(beanFactory);
|
||
|
||
try {
|
||
// Allows post-processing of the bean factory in context subclasses.
|
||
postProcessBeanFactory(beanFactory);
|
||
|
||
// Invoke factory processors registered as beans in the context.
|
||
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();
|
||
}
|
||
|
||
catch (BeansException ex) {
|
||
if (logger.isWarnEnabled()) {
|
||
logger.warn("Exception encountered during context initialization - " +
|
||
"cancelling refresh attempt: " + ex);
|
||
}
|
||
|
||
// Destroy already created singletons to avoid dangling resources.
|
||
destroyBeans();
|
||
|
||
// Reset 'active' flag.
|
||
cancelRefresh(ex);
|
||
|
||
// Propagate exception to caller.
|
||
throw ex;
|
||
}
|
||
|
||
finally {
|
||
// Reset common introspection caches in Spring's core, since we
|
||
// might not ever need metadata for singleton beans anymore...
|
||
resetCommonCaches();
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|