springboot启动配置原理

1、生成SpringApplication对象

@SpringBootApplication
public class SpringBoot06DataMybatisApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringBoot06DataMybatisApplication.class, args);
	}
}

在run打断点debug运行,进入run方法

public static ConfigurableApplicationContext run(Object source, String... args) {
		return run(new Object[] { source }, args);
	}

继续进入run方法

public SpringApplication(Object... sources) {
		initialize(sources);
}

进入initialize方法

public class SpringApplication {
	private final Set<Object> sources = new LinkedHashSet<Object>();
	
	.......................
	
	private static final String[] WEB_ENVIRONMENT_CLASSES = { "javax.servlet.Servlet",
			"org.springframework.web.context.ConfigurableWebApplicationContext" };

	private void initialize(Object[] sources) {
			if (sources != null && sources.length > 0) {
				//给sources赋值,复制成为主配置类
				this.sources.addAll(Arrays.asList(sources));
			}
			//判断是否是web环境,通过判断servlet和ConfigurableWebApplicationContext是否存在
			this.webEnvironment = deduceWebEnvironment();
			//设置初始化器通过传递应用容器初始化器参数,从META-INF/spring.factories	里加载
			setInitializers((Collection) getSpringFactoriesInstances(
					ApplicationContextInitializer.class));
			//设置监听器器通过传递应用监听器参数,从META-INF/spring.factories	里加载
			setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
			this.mainApplicationClass = deduceMainApplicationClass();
	}
	
	private boolean deduceWebEnvironment() {
		for (String className : WEB_ENVIRONMENT_CLASSES) {
			if (!ClassUtils.isPresent(className, null)) {
				return false;
			}
		}
		return true;
	}
	
	public void setInitializers(
			Collection<? extends ApplicationContextInitializer<?>> initializers) {
		this.initializers = new ArrayList<ApplicationContextInitializer<?>>();
		this.initializers.addAll(initializers);
	}
	
	private <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type,
			Class<?>[] parameterTypes, Object... args) {
		ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
		// Use names and ensure unique to protect against duplicates
		Set<String> names = new LinkedHashSet<String>(
				//
				SpringFactoriesLoader.loadFactoryNames(type, classLoader));
		//得到应用容器初始化器的实例对象
		List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
				classLoader, args, names);
		AnnotationAwareOrderComparator.sort(instances);
		return instances;
	}
}

从META-INF/spring.factories里加载得到初始化器名字的代码

public abstract class SpringFactoriesLoader {
	public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
		String factoryClassName = factoryClass.getName();
		try {
			Enumeration<URL> urls = (classLoader != null ? 
			//从		META-INF/spring.factories	里加载
			classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
					ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
			List<String> result = new ArrayList<String>();
			while (urls.hasMoreElements()) {
				URL url = urls.nextElement();
				Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
				String factoryClassNames = properties.getProperty(factoryClassName);
				result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));
			}
			return result;
		}
		catch (IOException ex) {
			throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() +
					"] factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex);
		}
	}
}

获得的返回result值对象为在这里插入图片描述
而/META-INF/spring.factories文件
/META-INF/spring.factories

2、到这里完成了对springApplication初始化的工作,接着运行该类的run方法

public class SpringApplication {
	public ConfigurableApplicationContext run(String... args) {
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		//定义一些要用到的参数
		ConfigurableApplicationContext context = null;
		FailureAnalyzers analyzers = null;
		configureHeadlessProperty();
		//获得spring应用运行的监听器这里是,org.springframework.boot.context.event.EventPublishingRunListener
		SpringApplicationRunListeners listeners = getRunListeners(args);
		//运行监听器的starting方法
		listeners.starting();
		try {
			
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(
					args);
			//准备课配置的环境,传入两个参数,看下面的方法代码
			ConfigurableEnvironment environment = prepareEnvironment(listeners,
					applicationArguments);
			//打印spring的标识
			Banner printedBanner = printBanner(environment);
			//创建一个可配置的应用容器,请看下面代码
			context = createApplicationContext();
			analyzers = new FailureAnalyzers(context);
			//准备容器,传入监听器,环境,可配置的容器,还有参数,请看下面的方法代码
			prepareContext(context, environment, listeners, applicationArguments,
					printedBanner);
			//更新容器,也就是给容器传入各种需要的值,启动服务器,注册各种需要的组件,请看下面另一个类的方法
			refreshContext(context);
			//运行应用启动器,和命令行启动器
			afterRefresh(context, applicationArguments);
			//监听完成
			listeners.finished(context, null);
			stopWatch.stop();
			if (this.logStartupInfo) {
				new StartupInfoLogger(this.mainApplicationClass)
						.logStarted(getApplicationLog(), stopWatch);
			}
			return context;
		}
		catch (Throwable ex) {
			handleRunFailure(context, listeners, analyzers, ex);
			throw new IllegalStateException(ex);
		}
	}
	
	...........................
	
	private ConfigurableEnvironment prepareEnvironment(
			SpringApplicationRunListeners listeners,
			ApplicationArguments applicationArguments) {
		// Create and configure the environment
		//创建环境
		ConfigurableEnvironment environment = getOrCreateEnvironment();
		//调用方法,传入两个参数
		configureEnvironment(environment, applicationArguments.getSourceArgs());
		//调用监听器的environmentPrepared(准备好环境)方法
		listeners.environmentPrepared(environment);
		//判断是否为web环境
		if (!this.webEnvironment) {
			environment = new EnvironmentConverter(getClassLoader())
					.convertToStandardEnvironmentIfNecessary(environment);
		}
		return environment;
	}
	
	protected ConfigurableApplicationContext createApplicationContext() {
		Class<?> contextClass = this.applicationContextClass;
		if (contextClass == null) {
			try {
				//判断是否web环境来决定配置何种容器类
				contextClass = Class.forName(this.webEnvironment
						? DEFAULT_WEB_CONTEXT_CLASS : DEFAULT_CONTEXT_CLASS);
			}
			catch (ClassNotFoundException ex) {
				throw new IllegalStateException(
						"Unable create a default ApplicationContext, "
								+ "please specify an ApplicationContextClass",
						ex);
			}
		}
		return (ConfigurableApplicationContext) BeanUtils.instantiate(contextClass);
	}
	
	........................
	
	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
		context.getBeanFactory().registerSingleton("springApplicationArguments",
				applicationArguments);
		if (printedBanner != null) {
			context.getBeanFactory().registerSingleton("springBootBanner", printedBanner);
		}

		// Load the sources
		Set<Object> sources = getSources();
		Assert.notEmpty(sources, "Sources must not be empty");
		load(context, sources.toArray(new Object[sources.size()]));
		listeners.contextLoaded(context);
	}
	
	..........................
	
	protected void postProcessApplicationContext(ConfigurableApplicationContext context) {
		if (this.beanNameGenerator != null) {
			//利用容器得到对象工厂,然后注册单实例组件
			context.getBeanFactory().registerSingleton(
					AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR,
					this.beanNameGenerator);
		}
		if (this.resourceLoader != null) {
			if (context instanceof GenericApplicationContext) {
				((GenericApplicationContext) context)
						.setResourceLoader(this.resourceLoader);
			}
			if (context instanceof DefaultResourceLoader) {
				((DefaultResourceLoader) context)
						.setClassLoader(this.resourceLoader.getClassLoader());
			}
		}
	}
}
public abstract class AbstractApplicationContext extends DefaultResourceLoader
		implements ConfigurableApplicationContext, DisposableBean {

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

进入afterRefresh

public class SpringApplication {
	private void callRunners(ApplicationContext context, ApplicationArguments args) {
			List<Object> runners = new ArrayList<Object>();
			runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
			runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
			AnnotationAwareOrderComparator.sort(runners);
			for (Object runner : new LinkedHashSet<Object>(runners)) {
				if (runner instanceof ApplicationRunner) {
					callRunner((ApplicationRunner) runner, args);
				}
				if (runner instanceof CommandLineRunner) {
					callRunner((CommandLineRunner) runner, args);
				}
			}
		}
	
		private void callRunner(ApplicationRunner runner, ApplicationArguments args) {
			try {
				(runner).run(args);
			}
			catch (Exception ex) {
				throw new IllegalStateException("Failed to execute ApplicationRunner", ex);
			}
		}
}

至此结束springboot应用的启动

3、自定义listener,Initializer和ApplicationRunner,CommandLineRunner

public class HelloApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        System.out.println("ApplicationContextInitializer...initialize..."+applicationContext);
    }
}
@Component
class HelloApplicationRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("ApplicationRunner...run....");
    }
}
@Component
public class HelloCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("CommandLineRunner...run..."+ Arrays.asList(args));
    }
}
public class HelloSpringApplicationRunListener implements SpringApplicationRunListener {

    //必须有的构造器
    public HelloSpringApplicationRunListener(SpringApplication application, String[] args){

    }

    @Override
    public void starting() {
        System.out.println("SpringApplicationRunListener...starting...");
    }

    @Override
    public void environmentPrepared(ConfigurableEnvironment environment) {
        Object o = environment.getSystemProperties().get("os.name");
        System.out.println("SpringApplicationRunListener...environmentPrepared.."+o);
    }

    @Override
    public void contextPrepared(ConfigurableApplicationContext context) {
        System.out.println("SpringApplicationRunListener...contextPrepared...");
    }

    @Override
    public void contextLoaded(ConfigurableApplicationContext context) {
        System.out.println("SpringApplicationRunListener...contextLoaded...");
    }

    @Override
    public void finished(ConfigurableApplicationContext context, Throwable exception) {
        System.out.println("SpringApplicationRunListener...finished...");
    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值