使用外置的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. [android] 练习使用ListView(二)

    主要练习异步任务和LruCache缓存 package com.android.test; import java.io.InputStream; import java.net.HttpURLCon ...

  2. windows 2003 安装 MVC 环境 404错误,无法找到该页

    在windows server 2003 IIS6 系统安装 DotNet 4.0 + MVC3 环境后, .cshtml 文件依然无法运行,404错误 解决方案:查看处理程序隐射,如果没有.csht ...

  3. 2018.10.26NOIP模拟赛解题报告

    心路历程 预计得分:\(100 + 100 + 70\) 实际得分:\(40 + 100 + 70\) 妈妈我又挂分了qwq..T1过了大样例就没管,直到临考试结束前\(10min\)才发现大样例是假 ...

  4. html简介(自己理解和老师讲课)

    首先讲开发网页三种技术:html,css,javascript.html负责网页的结构,css站在没学角度对网页进行美化,javascript负责网页交互,站在用户体验角度设计网页交互效果 而我们所学 ...

  5. 扩展运算符&reset运算符

    扩展运算符用三个点号表示,功能是把数组或类数组对象展开成一系列用逗号隔开的值 var foo = function(a, b, c) { console.log(a); console.log(b); ...

  6. 52张扑克牌快速生成js

    function* generatePoker() { const points = ['A', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K']; yield* ...

  7. Oracle基础之Merge into

    Merge into语句是Oracle9i新增的语法,用来合并UPDATE和INSERT语句. 通过MERGE语句,根据一张表或多表联合查询的连接条件对另外一张表进行查询,连接条件匹配上的进行UPDA ...

  8. 从数据库读取数据后将其输出成html标签

    最常用的方法,使用JS或JQ JQ: $("#div").html("<span>我是HTML代码</span>"); JS: var ...

  9. deb文件怎么安装

    deb 是 ubuntu .debian 的格式.rpm 是 redhat .fedora .suse 的格式.deb是debian发行版的软件包ubuntu是基于debian 发行的 所有可以用.d ...

  10. dctcp-2.6.26-rev1.1.0.patch

    dctcp-2.6.26-rev1.1.0.patch diff -Naur linux-/include/linux/sysctl.h linux--dctcp-rev1.1.0/include/l ...