SpringApplication.run(Xxxx.class)启动的源码解析Day2

阅读部分

事件监听,源码启动部分

SpringApplicationRunListeners listeners = getRunListeners(args);

getRunListeners(String[] args) {
		Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
		return new SpringApplicationRunListeners(logger,	getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));
}

getSpringFactoriesInstances看出调用了SpringBoot的工厂机制(spring.factories)生成实例对象。请注意这儿传递了两个参数(this, args),这为之后生成SpringApplicationRunListener实例做了铺垫。

在这里插入图片描述
listeners.starting();开启全部运行时监听器

跟进getSpringFactoriesInstances–>createSpringFactoriesInstances(),可以看到如何生成SpringApplicationRunListener实例

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;
	}

可以看到,先获取实现了SpringApplicationRunListener的类名;

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;
	}

BeanUtils.instantiateClass(constructor, args);将之前传递的两个参数放入构造器中实例化。

再回到run()方法中,listeners.starting();开启监听类,实现运用到了组合方法。

public void starting() {
		for (SpringApplicationRunListener listener : this.listeners) {
			listener.starting();
		}
	}
/**
	 * 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<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
        //检测即使没有检测到显示器,也允许启动
		configureHeadlessProperty();
        //获取所有配置在spring.factories的SpringApplicationRunListener
        //用到了工厂机制。
		SpringApplicationRunListeners listeners = getRunListeners(args);
        //组合模式开启SpringApplicationRunListener
		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 <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
    	//获取类加载器AppClassLoader@500c05c2
		ClassLoader classLoader = getClassLoader();
		//获取所有配置在spring.factories的ApplicationContextInitializer实例
    	//首先获取当前目录下的,再去找jar包里的
		Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
    	//实例化Bean
		List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
    	//将实现的Order接口或注解进行排序
		AnnotationAwareOrderComparator.sort(instances);
		return instances;
}

在这里插入图片描述
img

public ClassLoader getClassLoader() {
    //初始化时,resourceLoader是为空的,可以显示指定类加载器
		if (this.resourceLoader != null) {
			return this.resourceLoader.getClassLoader();
		}
    //返回默认默认使用启动类加载器作为父加载器AppClassLoader
		return ClassUtils.getDefaultClassLoader();
	}
public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {
        String factoryClassName = factoryClass.getName();
    //map.getOrDefault(k,v);有k则m.get(k),无对应k则返回指定v
        return (List)loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}
p.getOrDefault(k,v);有k则m.get(k),无对应k则返回指定v
        return (List)loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值