参考视频:
https://www.ixigua.com/7090148232243708446?wid_try=1
public class SpringApplication {
...
...
单参数构造方法
public SpringApplication(Class... primarySources) {
调用双参构造方法
this((ResourceLoader)null, primarySources);
}
双参数构造方法
public SpringApplication(ResourceLoader resourceLoader, Class... primarySources) {
这个构造函数相当于初始化各种属性参数等操作.......
在1.0之前这个构造函数是作为init方法存在.........
this.sources = new LinkedHashSet();
this.bannerMode = Mode.CONSOLE;
this.logStartupInfo = true;
this.addCommandLineProperties = true;
this.addConversionService = true;
this.headless = true;
this.registerShutdownHook = true;
this.additionalProfiles = Collections.emptySet();
this.isCustomEnvironment = false;
this.lazyInitialization = false;
this.applicationContextFactory = ApplicationContextFactory.DEFAULT;
this.applicationStartup = ApplicationStartup.DEFAULT;
this.resourceLoader = resourceLoader;
断言你传过来的字节码文件不能为空,如果为空就给你打印后面这句话
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
this.webApplicationType = WebApplicationType.deduceFromClasspath();
this.bootstrapRegistryInitializers = this.getBootstrapRegistryInitializersFromSpringFactories();
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = this.deduceMainApplicationClass();
}
...
...
run方法
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
生成一个新的数组,数组里存的是Class类型,这些class从哪来,从字节码文件中来。
return run(new Class[]{primarySource}, args);
}
...
...
另一个run方法
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
这里调用了SpringApplication的第一个构造函数
return (new SpringApplication(primarySources)).run(args);
}
...
...
另另一个run方法
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
springboot当中用到的最早的一个配置文件类型,它优先加载于application.properties
DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
ConfigurableApplicationContext context = null;
this.configureHeadlessProperty();
SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.starting(bootstrapContext, this.mainApplicationClass);
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
加载环境变量,运行起来控制台会输出类似的Starting Application using Java 1.8.0_131 on PC-202032 with PID 5060(D://.......)
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
this.configureIgnoreBeanInfo(environment);
控制台打印的花式文字
Banner printedBanner = this.printBanner(environment);
创建了spring的核心容器
context = this.createApplicationContext();
让你的核心容器跑起来
context.setApplicationStartup(this.applicationStartup);
预处理
this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
刷新整理
this.refreshContext(context);
最后刷新
this.afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
}
listeners.started(context);
this.callRunners(context, applicationArguments);
} catch (Throwable var10) {
this.handleRunFailure(context, var10, listeners);
throw new IllegalStateException(var10);
}
try {
listeners.running(context);
return context;
} catch (Throwable var9) {
this.handleRunFailure(context, var9, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var9);
}
}
}
@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) { // 调用了当前类下的另一个run方法 return run(new Class[]{primarySource}, args); } public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) { // 在当前类下的另一个run方法中 调用了当前类的单参构造方法 return (new SpringApplication(primarySources)).run(args); } public SpringApplication(Class... primarySources) { // 单参构造方法中,又去调用了双参构造方法 this((ResourceLoader)null, primarySources); }
// 在双参构造方法中有这么一个ApplicationContextFactory this.applicationContextFactory = ApplicationContextFactory.DEFAULT;
public class StopWatch {
... ... public void start(String taskName) throws IllegalStateException { if (this.currentTaskName != null) { throw new IllegalStateException("Can't start StopWatch: it's already running"); } else { this.currentTaskName = taskName; this.startTimeNanos = System.nanoTime(); } } }
它这个run要这个类的字节码有什么用呢? 它这个类上面的注解@SpringBootApplication
SpringUtils中的setApplicationContext到底什么时候被执行了?今天我们研究一下。
参考链接:ApplicationContextAware接口的setApplicationContext方法调用过程_大家说的博客-CSDN博客_setapplicationcontext方法
@Component
public class SpringUtils implements ApplicationContextAware {
...
...
...
private ApplicationContext applicationContext;
private BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition();
private DefaultListableBeanFactory autowireCapableBeanFactory;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (this.applicationContext == null) {
this.applicationContext = applicationContext;
}
}
...
...
}
SpringApplication.java:
public class SpringApplication {
...
...
/**
* Refresh the underlying {@link ApplicationContext}.
* @param applicationContext the application context to refresh
*/
protected void refresh(ConfigurableApplicationContext applicationContext) {
applicationContext.refresh();
}
...
...
}
点击refresh进入ConfigurableApplicationContext 接口
public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable {
....
....
void refresh() throws BeansException, IllegalStateException;
....
....
}
点击抽象方法refresh() ,进入实现类AbstractApplicationContext.java
在refresh()方法中 点击this.prepareBeanFactory(beanFactory);// 点击进入查看prepareBeanFactory()
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
...
...
public void refresh() throws BeansException, IllegalStateException {
Object var1 = this.startupShutdownMonitor;
synchronized(this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
1这里---->this.prepareBeanFactory(beanFactory);//---->beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));---->ApplicationContextAwareProcessor.java
try {
this.postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
4这里---->this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var10) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var10);
}
this.destroyBeans();
this.cancelRefresh(var10);
throw var10;
} finally {
this.resetCommonCaches();
contextRefresh.end();
}
}
}
...
...
...
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.setBeanClassLoader(this.getClassLoader());
if (!shouldIgnoreSpel) {
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
2这里---->beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
3这里---->ApplicationContextAwareProcessor.java
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
if (!NativeDetector.inNativeImage() && beanFactory.containsBean("loadTimeWeaver")) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
if (!beanFactory.containsLocalBean("environment")) {
beanFactory.registerSingleton("environment", this.getEnvironment());
}
if (!beanFactory.containsLocalBean("systemProperties")) {
beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean("systemEnvironment")) {
beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment());
}
if (!beanFactory.containsLocalBean("applicationStartup")) {
beanFactory.registerSingleton("applicationStartup", this.getApplicationStartup());
}
}
....
....
5这里---->protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
}
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver((strVal) -> {
return this.getEnvironment().resolvePlaceholders(strVal);
});
}
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
String[] var3 = weaverAwareNames;
int var4 = weaverAwareNames.length;
for(int var5 = 0; var5 < var4; ++var5) {
String weaverAwareName = var3[var5];
this.getBean(weaverAwareName);
}
beanFactory.setTempClassLoader((ClassLoader)null);
beanFactory.freezeConfiguration();
6这里---->beanFactory.preInstantiateSingletons();
}
....
}
在AbstractApplicationContext .java的refresh()的prepareBeanFactory()中查看:beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
我们看到一个new ApplicationContextAwareProcessor(this)类,这个类是一个BeanPostProcessor类型的类。OK,我们先在这里有一个印象,就是在BeanFactory里面加入了一个 ApplicationContextAwareProcessor。
这个过程就是ApplicationContextAwareProcessor的装配过程。
---------------------------------------------------------------------------
AbstractApplicationContext.java的refresh()方法中继续往下执行,执行到AbstractApplicationContext .java的实例化bean的方法
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
代码执行到这个方法。
- protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory)
在AbstractApplicationContext.java的finishBeanFactoryInitialization()方法中:
会执行beanFactory.preInstantiateSingletons();
最终会执行到:
- AbstractAutowireCapableBeanFactory#doCreateBean方法
方法当中:
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
点进去
这个方法就是调用 ApplicationContextAwareProcessor的地方,我们进去看看。
我们可以看到,确实在BeanPostProcessors容器中有一个ApplicationContextAwareProcessor类。那么我们进到ApplicationContextAwareProcessor这个类的postProcessBeforeInitialization方法中。
根据这个源码,我们知道了,确实调用到了setApplicationContext()方法。