您的位置:首页 > 编程语言 > Java开发

深入剖析Spring Boot(一)应用搭建和启动

2018-06-04 14:31 218 查看

前言

现在后台应用开发中,随着微服务的理念越来越流行,新项目一般都是采用SpringBoot快速搭建,无需之前复杂的xml配置,一个注解,几行代码,程序完全能正常运行。Convertion over Configuration 也是应用开发中的一个趋势,通过对Spring和SpringBoot的学习,打算把自己的一些理解和心得记录下来,写成一个系列,与其说叫SpringBoot深入剖析,不如说Spring深入剖析,SpringBoot只是对Spring的一小部分扩展,通过自动化配置取代了之前xml的配置形式,后续分析中可以很明确发现这一点。

Spring Boot 应用

一般来说,SpringBoot应用一般长这个样子:

@SpringBootApplication
public class Application {

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

}

在配上一个Controller,一个最简单的应用就搭建完成;当然SpringBoot还提供了一种可以对Application进一步扩展的方式:SpringApplicationBuilder

@SpringBootApplication
public class Application {

public static void main(String[] args) {
new SpringApplicationBuilder()
.sources(Parent.class)
.child(Application.class)
.bannerMode(Banner.Mode.OFF)
.run(args);
}

}

这还不算完,你仍然可以进一步扩展,SpringApplicationBuilder内部实现来看是新建了一个SpringApplication,然后设置一系列的属性,那么我们是否可以继承SpringApplication来实现更多的扩展需求,答案是肯定的。SpringBoot的注释也明确说明(我一直觉得很多优秀的开源框架注释非常值得一读)。

SpringApplicationBuilder 中createSpringApplication方法中,使用了protected关键字(对Sping这个极讲究的框架而言,这个关键字几乎说明了是可扩展的)并且说明子类可以覆盖并生成自定义的SpringApplication,下面是个简单的例子来说明如何自定义我们的Application:

@SpringBootApplication
public class MyApplication extends SpringApplication {

public MyApplication() {
}

public MyApplication(Class<?>... primarySources) {
super(primarySources);
}

@Override
protected ConfigurableApplicationContext createApplicationContext() {
return super.createApplicationContext();
}

public static class MyApplicationBuilder extends SpringApplicationBuilder{

public MyApplicationBuilder() {
super(MyApplication.class);
this.bannerMode(Banner.Mode.OFF);
}

@Override
protected SpringApplication createSpringApplication(Class<?>... sources) {
return new MyApplication(sources);
}
}

public static void main(String[] args) {
new MyApplication.MyApplicationBuilder().run(args);
}
}

例子中只是简单的扩展,通过重写createApplicationContext()方法我们可以实现自己特殊需求的应用上下文,SpringApplication提供的扩展有很多,感兴趣的话可以点进去根据不同需求做进一步扩展。

启动原理

理解SpringBoot应用的构建后,我们看到启动的起点是SpringApplication的run()方法,先忽略掉部分无关大局的细节代码,启动过程最关键的两步是:

context = createApplicationContext();
refreshContext(context);

这里可以停下简单回想在SpringBoot以前应用是如何创建ApplicationContext的,正常来说我们会在web.xml中配置DispatcherServlet:

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<servlet>
<servlet-name>dispatch</servlet>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcherServlet.xml</param-value>
</init-param>

配置的listener 会在容器启动时创建Root 上下文,然后会初始化DispatchServlet,在initServletBean()时创建web应用上下文;在SpringBoot中,servlet容器是内置的,在程序启动时容器还并未初始化。SpringBoot通过简单的判断应用环境决定创建的上下文环境:

switch(this.webApplicationType) {
case SERVLET:
ontextClass = Class.forName("org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext");
break;
case REACTIVE:
contextClass = Class.forName("org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext");
break;
default:
contextClass = Class.forName("org.springframework.context.annotation.AnnotationConfigApplicationContext");
}

webApplicationType 的判断是在classPath中寻找特定的类,在导入springmvc的依赖后,SpringApplication找到”javax.servlet.Servlet”,
“org.springframework.web.context.ConfigurableWebApplicationContext”,判定为Servlet Web应用,于是会创建AnnotationConfigServletWebServerApplicationContext,有了ApplicationContext,接下来就是刷新了:

protected void refresh(ApplicationContext applicationContext) {
Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);
((AbstractApplicationContext) applicationContext).refresh();
}

我们看到,最终还是到了可以说是Spring最核心的refresh模板方法,这些方法中,不同的Applicatcontext实现上有很大的差别,举个例子:SpringBoot应用一般是纯注解的,那么在refreshBeanFactory() 方法中,它是不会做事情的,相反XmlClassPathApplicationContext中关于xml配置的解析都是在这里完成的。

本篇就到这里,后续会详细讲解SpringBoot的上下文是如何实现各个模板方法的以及和常规实现的一些区别;

总结

通过对Spring应用创建和启动的初步分析,我们可以看到,SpringBoot其实是简单的一层壳子,是基于Spring通过自动化配置简化了之前复杂的配置文件,使得程序员上手和开发更加方便,高效。

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: