使用外置的Servlet

 
嵌入式Servlet容器:应用打成可执行的j ar
优点:简单、便携;
缺点:默认不支持JSP、优化定制比较复杂
        使用定制器【ServerProperties、自定义
        EmbeddedServletContainerCustomizer】,
        自己编写嵌入式Servlet容器的创建工厂
        EmbeddedServletContainerFactory】
 
外置的Servlet容器:外面安装Tomcat---应用war包的方式打包
 
创建工程的时候使用war包

添加xml配置文件

 
 添加外部的服务器:

完成hello.jsp页面的跳转

hello.jsp

test.jsp

test.java

测试:

总结:
1)、必须创建一个war项目;(利用idea创建好目录结构
2)、将嵌入式的Tomcat指定为provided
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>

3)、必须编写一个SpringBootServletInitializer的子类,并调用configure方法

4)、启动服务器就可以使用

原理:

jar包:执行SpringBoot主类的main方法,启动ioc容器,创建嵌入式的Servlet容器
 
war包:启动服务器,服务器启动SpringBoot应用【SpringBootServletInitializer】,启动ioc容器
 
 
servlet3.0(Spring注解版)
章节:8.2.4 Shared libraries / runtimes pluggability
规则:
1)、服务器启动(web应用启动)会创建当前web应用里面每一个jar包里面ServletContainerInitializer实例:
2)、ServletContainerInitializer的实现放在jar包的META-INF/services文件夹下,有一个名为
        javax.servlet.ServletContainerInitializer的全类名
3)、还可以使用@HandlesTypes,在应用启动的时候加载我们感兴趣

流程:

1)、启动Tomcat
2)、org\springframework\spring-web\4.3.14.RELEASE\spring-web-         5.1.3.RELEASE.jar!\METAINF\services\javax.servlet.ServletContainerInitializer:
  Spring的web模块里面有这个文件:

3)、SpringServletContainerInitializer将@HandlesTypes(WebApplicationInitializer.class)标注的所
  有这个类型的类都传入到onStartup方法的Set>;为这些WebApplicationInitializer类型的类创建实例;
@HandlesTypes({WebApplicationInitializer.class})
public class SpringServletContainerInitializer implements ServletContainerInitializer {
public SpringServletContainerInitializer() {
} public void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext) throws ServletException {
List<WebApplicationInitializer> initializers = new LinkedList();
Iterator var4;
if (webAppInitializerClasses != null) {
var4 = webAppInitializerClasses.iterator(); while(var4.hasNext()) {
Class<?> waiClass = (Class)var4.next();
if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) && WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
try {
initializers.add((WebApplicationInitializer)ReflectionUtils.accessibleConstructor(waiClass, new Class[]).newInstance());
} catch (Throwable var7) {
throw new ServletException("Failed to instantiate WebApplicationInitializer class", var7);
}
}
}
} if (initializers.isEmpty()) {
servletContext.log("No Spring WebApplicationInitializer types detected on classpath");
} else {
servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");
AnnotationAwareOrderComparator.sort(initializers);
var4 = initializers.iterator(); while(var4.hasNext()) {
WebApplicationInitializer initializer =
(WebApplicationInitializer)var4.next();
initializer.onStartup(servletContext);

}}}}
4)、每一个WebApplicationInitializer都调用自己的onStartup;
WebApplicationInitializer的实现

是我们自己的Servletinitializer类
5)、相当于我们的SpringBootServletInitializer的类会被创建对象,并执行onStartup方法
6)、SpringBootServletInitializer实例执行onStartup的时候会createRootApplicationContext;创建容器
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(WebJspApplication.class);
}
}

 SpringBootServletInitializer.java

public void onStartup(ServletContext servletContext) throws ServletException {
this.logger = LogFactory.getLog(this.getClass());
WebApplicationContext rootAppContext = this.createRootApplicationContext(servletContext);
if (rootAppContext != null) {
servletContext.addListener(new ContextLoaderListener(rootAppContext) {
public void contextInitialized(ServletContextEvent event) {
}
});
} else {
this.logger.debug("No ContextLoaderListener registered, as createRootApplicationContext() did not return an application context");
}
} .....
protected WebApplicationContext createRootApplicationContext(
ServletContext servletContext) {
//1、创建SpringApplicationBuilder
SpringApplicationBuilder builder = createSpringApplicationBuilder();
StandardServletEnvironment environment = new StandardServletEnvironment();
environment.initPropertySources(servletContext, null);
builder.environment(environment);
builder.main(getClass());
ApplicationContext parent = getExistingRootWebApplicationContext(servletContext);
if (parent != null) {
this.logger.info("Root context already created (using as parent).");
servletContext.setAttribute(
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, null);
builder.initializers(new ParentContextApplicationContextInitializer(parent));
}
builder.initializers(
new ServletContextApplicationContextInitializer(servletContext));
builder.contextClass(AnnotationConfigEmbeddedWebApplicationContext.class); //调用configure方法,子类重写了这个方法,将SpringBoot的主程序类传入了进来
builder = configure(builder); //使用builder创建一个Spring应用
SpringApplication application = builder.build();
if (application.getSources().isEmpty() && AnnotationUtils
.findAnnotation(getClass(), Configuration.class) != null) {
application.getSources().add(getClass());
}
Assert.state(!application.getSources().isEmpty(),
"No SpringApplication sources have been defined. Either override the "
+ "configure method or add an @Configuration annotation");
// Ensure error pages are registered
if (this.registerErrorPageFilter) {
application.getSources().add(ErrorPageFilterConfiguration.class);
}
//启动Spring应用
return run(application);
}
7)、Spring的应用就启动并且创建IOC容器

public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
this.configureHeadlessProperty();
SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.starting(); Collection exceptionReporters;
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
this.configureIgnoreBeanInfo(environment);
Banner printedBanner = this.printBanner(environment);
context = this.createApplicationContext();
exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
this.prepareContext(context, environment, listeners, applicationArguments, printedBanner); //刷新容器的初始化
this.refreshContext(context);
this.afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
} listeners.started(context);
this.callRunners(context, applicationArguments);
} catch (Throwable var10) {
this.handleRunFailure(context, var10, exceptionReporters, listeners);
throw new IllegalStateException(var10);
} try {
listeners.running(context);
return context;
} catch (Throwable var9) {
this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var9);
}
}

19、配置嵌入式servlet容器(下)的更多相关文章

  1. 17、配置嵌入式servlet容器(1)

    SpringBoot默认使用Tomcat作为嵌入式的Servlet容器 1).如何定制和修改Servlet容器的相关配置         1.修改和server有关的配置            (Se ...

  2. 17. Spring Boot 配置嵌入式Servlet容器

    一.如何定制和修改Servlet容器的相关配置 1.配置文件(ServerProperties): 优先级最高 server.port=8081 server.context‐path=/crud s ...

  3. SpringBoot配置嵌入式Servlet容器

    1).如何定制和修改Servlet容器的相关配置: 1.修改和server有关的配置(ServerProperties[也是EmbeddedServletContainerCustomizer]): ...

  4. 配置嵌入式Servlet容器

    SpringBoot默认是用的是Tomcat作为嵌入式的Servlet容器:问题?1).如何定制和修改Servlet容器的相关配置:1.修改和server有关的配置(ServerProperties) ...

  5. 18、配置嵌入式servlet容器(2)

    使用其他Servlet容器 -Jetty(长连接) -Undertow(不支持jsp) 替换为其他嵌入式Servlet容器   默认支持: Tomcat(默认使用) Jetty: <depend ...

  6. 【串线篇】spring boot配置嵌入式servlet容器

    SpringBoot默认使用Tomcat作为嵌入式的Servlet容器 问题? 一.如何定制和修改Servlet容器的相关配置 1.方法1修改和server有关的配置(ServerProperties ...

  7. SpringBoot起飞系列-配置嵌入式Servlet容器(八)

    一.前言 springboot中默认使用的是tomcat容器,也叫做嵌入式的servlet容器.因为它和我们平常使用的tomcat容器不一样,这个tomcat直接嵌入到的springboot,平常我们 ...

  8. Spring boot 配置嵌入式Servlet容器

    SpringBoot默认使用Tomcat作为嵌入式的Servlet容器 1.修改和server有关的配置(ServerProperties[也是EmbeddedServletContainerCust ...

  9. springboot(七) 配置嵌入式Servlet容器

    github代码地址:https://github.com/showkawa/springBoot_2017/tree/master/spb-demo/spb-brian-query-service ...

随机推荐

  1. 原创:微信小程序java实现AES解密并获取unionId

    来自:微信小程序联盟 如果大家使用小程序的同时还在使用公众号的话,可能会用到unionId这种功能,由于公司业务需要,我们需要使用unionId,具体使用方法,请参考微信开放平台的说明,但是在微信小程 ...

  2. 从零开始制作H5人脸融合小游戏

    去年的建军节,一个展示军装照的H5人脸融合游戏火遍朋友圈,带来很好的传播效果.最近欧冠决赛要来了,公司决定做一个寻找和你最像的欧冠球星的H5游戏,那么该怎么做呢?认真分析了一下,这个游戏其实用到的技术 ...

  3. mybatis学习之动态sql

    mybatis的动态sql语句很强大,在mapper映射文件中使用简单的标签即可实现该效果,下面一个个记录: 1.select查询 简单的select类似如下: <select id=" ...

  4. git必会必知

    1 前言 git前身是BitKeeper,但是他不是开源软件,不符合当时开源趋势,于是就会有了开源的git,git开发只用了十天时间.目前git是公司开发必不可少的一个工具,用于多人开发的分布式版本控 ...

  5. kafka-php

    kafka-php kafka-php的github地址  https://github.com/jacky5059/kafka-php 生产者produce示例代码 <?php set_inc ...

  6. linux chkconfig 使用说明

    原文 chkconfig是管理系统服务(service)的命令行工具.所谓系统服务(service),就是随系统启动而启动,随系统关闭而关闭的程序. chkconfig可以更新(启动或停止)和查询系统 ...

  7. 读ios开发有感——建立APP开发体系

    前言:ios开发和现在的大前端.跨端开发在底层上的道理是相通的,因此通过学习ios开发,可以形成对APP开发体系的理解. 一.app开发的知识体系 基础 应用开发 原理 原生与前端 二.基础模块 按照 ...

  8. 微信小程序,动态改变样式

    小程序目前没有修改样式api,但是可以利用数据绑定实现动态改变样式,可以用view标签模拟page然后改变view标签的样式,以下案例演示了如果改变page背景颜色: <view class=& ...

  9. Bzoj3105:[CQOI2013]新Nim游戏

    题面 传送门 Sol 也是拿出一些数,使剩下的异或起来不为\(0\) 而线性基内的数异或不出\(0\) 那么从大到小加到线性基内 然后中途为\(0\)了,就取走它 这样我们使最大的在线性基内,剩下的是 ...

  10. Android错题集

    在Android学习的过程中,遇到过很多迷之问题,在这里记下以防以后忘记,也可以顺便帮助一下遇到了相同问题的朋友. 1.自定义控件文字大小错误: 在自定义控件中获取的getDimension值为px值 ...