springboot源码解析-SpringApplication

说明

用过springboot的人应该都知道SpringApplication做boot的一个启动点,但是有多少人知道这个类做了多少事情?
我们来看下源码里面的解释:
可以通过java主程序(main)来启动spring应用,执行时需要按照以下步骤执行:

1、创建一个实例应用也就是程序;

2、注册一个资源文件来执行spring属性也就是ResourceLoader需要做的事情;

3、刷新应用程序的上下文,加载所有的单例bean;

4、触发一些需要执行的bean,指的是监听和runner;

几种启动方式

实现方式

第一种
SpringApplication.run(Application.class, args);

第二种
SpringApplication.main(args);

第三种

SpringApplication springApplication = new SpringApplication(Application.class);
springApplication.run(args);

说明

前面两种SpringApplication的一个静态方法run,通过run构造一个SpringApplication对象,一般直接启动会直接选择第一种;第二种我觉得作用不大,因为需要构造primarySource资源,第三种一般需要改造启动类,做一些定制化代码。

/**
	 * 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);
	}

	/**
	 * 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);
	}
		/**
	 * A basic main that can be used to launch an application. This method is useful when
	 * application sources are defined via a {@literal --spring.main.sources} command line
	 * argument.
	 * <p>
	 * Most developers will want to define their own main method and call the
	 * {@link #run(Class, String...) run} method instead.
	 * @param args command line arguments
	 * @throws Exception if the application cannot be started
	 * @see SpringApplication#run(Class[], String[])
	 * @see SpringApplication#run(Class, String...)
	 */
	public static void main(String[] args) throws Exception {
		SpringApplication.run(new Class<?>[0], args);
	}

参数说明

运行run方法会用两个参数primarySource、args

primarySource:主要是用于创建一个实例bean,通过这个主类加载应用的上下文,相当于所有bean的源头;

args:主要用于参数传递

SpringAppication构造方法

1、初始化资源,启动传的值为null;

 public SpringApplication(Class<?>... primarySources) {
		this(null, primarySources);
	}

2、设置bean的来源,这个是必须要有的;

this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));

3、推断SpringBoot的应用类型,主要分为SERVLET:基于servlet启动的应用,默认是这个;REACTIVE:基于Reactive Web启动的用于;

this.webApplicationType = deduceWebApplicationType();

4、初始化上下文初始化器;

setInitializers((Collection) getSpringFactoriesInstances(
				ApplicationContextInitializer.class));

5、加载应用事件监听器

setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));

6、运行SpringApplication

/**
	 * Create a new {@link SpringApplication} instance. The application context will load
	 * beans from the specified primary sources (see {@link SpringApplication class-level}
	 * documentation for details. The instance can be customized before calling
	 * {@link #run(String...)}.
	 * @param resourceLoader the resource loader to use
	 * @param primarySources the primary bean sources
	 * @see #run(Class, String[])
	 * @see #setSources(Set)
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	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 = deduceWebApplicationType();
		setInitializers((Collection) getSpringFactoriesInstances(
				ApplicationContextInitializer.class));
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
		this.mainApplicationClass = deduceMainApplicationClass();
	}
发布了75 篇原创文章 · 获赞 85 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/zhangchangbin123/article/details/89348668