主体脉络
This commit is contained in:
parent
28008b39b0
commit
364ba4a6c9
|
@ -1,255 +0,0 @@
|
||||||
## 启动简单流程
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
### Create a new SpringApplication instance.
|
||||||
|
|
||||||
|
1. 配置资源加载器
|
||||||
|
2. 主类加载器
|
||||||
|
3. 设置应用类型
|
||||||
|
4. 实例化上下文ApplicationContextInitializer
|
||||||
|
5. 实例化监听器ApplicationListener
|
||||||
|
6. 查找主函数
|
||||||
|
|
||||||
|
### Run the Spring application, creating and refreshing a new ApplicationContext.
|
||||||
|
|
||||||
|
1. 设置头信息java.awt.headless
|
||||||
|
2. 创建运行监听器 SpringApplicationRunListener
|
||||||
|
2. 准备环境ConfigurableEnvironment
|
||||||
|
2. 初始化上下文ConfigurableApplicationContext
|
||||||
|
2. 准备上下文
|
||||||
|
2. 刷新上下文
|
||||||
|
2. 启动监听器ApplicationListener
|
||||||
|
2. 启动ApplicationRunner
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,6 @@
|
||||||
Bean 'org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$69797ab5] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
|
Bean 'org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$69797ab5] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```java
|
```java
|
||||||
SpringApplication.run(PrimarySources.class, args);
|
SpringApplication.run(PrimarySources.class, args);
|
||||||
```
|
```
|
||||||
|
@ -17,6 +13,8 @@ new SpringApplication(primarySources)
|
||||||
setInitializers ApplicationContextInitializer.class
|
setInitializers ApplicationContextInitializer.class
|
||||||
setListeners ApplicationListener.class
|
setListeners ApplicationListener.class
|
||||||
Class.forName(stackTraceElement.getClassName())
|
Class.forName(stackTraceElement.getClassName())
|
||||||
|
|
||||||
|
getSpringFactoriesInstances从META-INF/spring.factories获取实例通过反射创建
|
||||||
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
|
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
|
||||||
MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
|
MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
|
@ -84,7 +82,8 @@ listeners.starting()
|
||||||
DefaultApplicationArguments (new SimpleCommandLineArgsParser()).parse(args)
|
DefaultApplicationArguments (new SimpleCommandLineArgsParser()).parse(args)
|
||||||
```
|
```
|
||||||
|
|
||||||
```java
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
|
准备环境
|
||||||
|
|
||||||
|
设置转换器
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
## 获取类实例
|
||||||
|
|
||||||
|
```java
|
||||||
|
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type) {
|
||||||
|
return getSpringFactoriesInstances(type, new Class<?>[] {});
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## spring工厂中加载类名
|
||||||
|
|
||||||
|
```java
|
||||||
|
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
|
||||||
|
String factoryTypeName = factoryType.getName();
|
||||||
|
return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```java
|
||||||
|
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
|
||||||
|
MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
|
||||||
|
if (result != null) {
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
|
||||||
|
MultiValueMap<String, String> result = new LinkedMultiValueMap();
|
||||||
|
|
||||||
|
while(urls.hasMoreElements()) {
|
||||||
|
URL url = (URL)urls.nextElement();
|
||||||
|
UrlResource resource = new UrlResource(url);
|
||||||
|
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
|
||||||
|
Iterator var6 = properties.entrySet().iterator();
|
||||||
|
|
||||||
|
while(var6.hasNext()) {
|
||||||
|
Map.Entry<?, ?> entry = (Map.Entry)var6.next();
|
||||||
|
String factoryTypeName = ((String)entry.getKey()).trim();
|
||||||
|
String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
|
||||||
|
int var10 = var9.length;
|
||||||
|
|
||||||
|
for(int var11 = 0; var11 < var10; ++var11) {
|
||||||
|
String factoryImplementationName = var9[var11];
|
||||||
|
result.add(factoryTypeName, factoryImplementationName.trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cache.put(classLoader, result);
|
||||||
|
return result;
|
||||||
|
} catch (IOException var13) {
|
||||||
|
throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```java
|
||||||
|
private <T> List<T> createSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes,
|
||||||
|
ClassLoader classLoader, Object[] args, Set<String> names) {
|
||||||
|
List<T> instances = new ArrayList<>(names.size());
|
||||||
|
for (String name : names) {
|
||||||
|
try {
|
||||||
|
Class<?> instanceClass = ClassUtils.forName(name, classLoader);
|
||||||
|
Assert.isAssignable(type, instanceClass);
|
||||||
|
Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes);
|
||||||
|
T instance = (T) BeanUtils.instantiateClass(constructor, args);
|
||||||
|
instances.add(instance);
|
||||||
|
}
|
||||||
|
catch (Throwable ex) {
|
||||||
|
throw new IllegalArgumentException("Cannot instantiate " + type + " : " + name, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return instances;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
Loading…
Reference in New Issue