使用外置的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. mysql的线程处于System lock状态下

    The thread has called mysql_lock_tables() and the thread state has not been updated since. This is a ...

  2. NoSQL集锦

    1. http://blog.nosqlfan.com/,有不少Redis.CouchDB.MongoDB的电子书和文章,但没有Memcached的.

  3. 关于asp.net假分页的删除操作的随笔

    作为一个新人,上周负责优化一个后台管理系统,遇到一个问题:点击删除按钮之后,页面又回到了第一页. 而我需要达到的效果是:点击了删除按钮之后,原来是那一页,删除后还是在那一页. 由于项目是已经验收了的, ...

  4. [PHP] Oauth授权和本地加密

    1.Oauth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方 关键字:appKey appSecre ...

  5. java.lang.UnsupportedClassVersionError: action/Login : Unsupported major.minor version 52.0 (unable to load class action.Login)异常

    用myeclipse新建一个web项目,用了struts2框架,tomcat启动的时候报了这个错误. 我的问题原因是tomcat7的运行环境不知道为什么设置成了myeclipse1.7的jre,我给它 ...

  6. 7、srpingboot改变JDK版本

    在pom.xml中加上 <plugin> <artifactId>maven-compiler-plugin</artifactId> <configurat ...

  7. C Primer Plus note7

    这个程序是<C Primer Plus 中文版 第六版>书上198页的代码,是一个值的琢磨的程式. 有时间可以看一看: 尤其是下面这几句代码,很精妙: 用了很短的程式,得出了最大值和最小值 ...

  8. 通过反射感知Redis类里边全部的操作方法

    <?php //通过反射感知Redis类里边全部的操作方法 //根据Redis类实例化一个反射类对象 $me = new ReflectionClass('Redis'); //获得Redis类 ...

  9. HOST文件配置

    HOST文件配置位置:C:\Windows\System32\drivers\etc\HOSTS 127.0.0.1 localhost 127.0.0.1 app.weilan.com 127.0. ...

  10. RegExp.prototype.exec()使用技巧

    RegExp.prototype.exec() exec() 方法在一个指定字符串中执行一个搜索匹配.返回一个结果数组或 null. 如果你只是为了判断是否匹配(true或 false),可以使用 R ...