文章目录
1.1基本依懒
<!--用于版本管理-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.0.RELEASE</version>
</parent>
<groupId>com.xie.java</groupId>
<artifactId>spring-boot-src</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
1.2模块介绍
从上图可以看到spring-boot 是基于spring实现的,应用spring-boot 一般要制作starter,下面分析组成的几个模块
- spring-boot-starter
该模块主要其它几个模块依赖组合在一起,实现就是一个pom文件,是没有源码 - spring-boot
核心模块,完全基于spring实现 - spring-boot-autoconfigure
自动配模块,基于spring-boot,预设一些常用框架的配置信息;基于依赖条件是否满足,如依赖条件满足则启用该框加配置;如mybatis,spring-aop这些框架;当然我们要自动配置这个框架首先基于spring-boot去制相应的starter - spring-core
这个不用说了
1.3简单启动代码
@EnableAutoConfiguration()//启用自动配置注解
@ComponentScan({"com.xie.java"})
public class MyBootApplication {
public static void main(String[] args) {
SpringApplication.run(MyBootApplication.class);
}
}
1.3 加载初始化器及application监听器
public SpringApplication(ResourceLoader resourceLoader, Object... sources) {
this.resourceLoader = resourceLoader;
initialize(sources);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private void initialize(Object[] sources) {
if (sources != null && sources.length > 0) {
this.sources.addAll(Arrays.asList(sources));
}
//检测是否为web环境
this.webEnvironment = deduceWebEnvironment();
//从META-INFO/spring-factories里获取ApplicationContextInitializer配置的application初始化器的实现
setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));
//同理获取spring-factories 里配置的 application监听器
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = deduceMainApplicationClass();
}
//找出main方法主类
private Class<?> deduceMainApplicationClass() {
try {
StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();
for (StackTraceElement stackTraceElement : stackTrace) {
if ("main".equals(stackTraceElement.getMethodName())) {
return Class.forName(stackTraceElement.getClassName());
}
}
}
catch (ClassNotFoundException ex) {
// Swallow and continue
}
return null;
}
1.4 SpringApplication.run 启动
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
configureHeadlessProperty();
//1.获取运行监听器,
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.started();
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(
args);
ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);
Banner printedBanner = printBanner(environment);
//2.创建applicationContext
context = createApplicationContext();
//3.启动前准备
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);
//4.刷新spring容器
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, ex);
throw new IllegalStateException(ex);
}
}
1.5创建application context
protected ConfigurableApplicationContext createApplicationContext() {
Class<?> contextClass = this.applicationContextClass;
if (contextClass == null) {
try {//实际创建的是”org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext"
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);
}
1.6 context 刷新前准备
private void prepareContext(ConfigurableApplicationContext context,
ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments, Banner printedBanner) {
context.setEnvironment(environment);
postProcessApplicationContext(context);
applyInitializers(context);
listeners.contextPrepared(context);//给监听器发送prepare事件
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加载所有资源配置信息,可以是xml或类什么的
Set<Object> sources = getSources();
Assert.notEmpty(sources, "Sources must not be empty");
load(context, sources.toArray(new Object[sources.size()]));//加载resource xml,annotation等资源
listeners.contextLoaded(context);
}
1.7 context ioc容器构建过程,因为这里分析的是spring-boot所以接下来只会重点跟invokeBeanFactoryPostProcessors 方法
//spring ioc容器构建过程方法
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
//1获取beanfactory
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.
//2.spring-boot 自动装配置关键入口
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
//3.注册所有BeanPostProcessor ,aop、代理生成 等扩展都与BeanPostProcessor接口实现相关
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.
//4.ioc 注入预生成实例
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();
}
}
}