Tomcat

StandardContext初始化过程

//org.apache.catalina.core.StandardContext#startInternal

  // 子容器启动
for (Container child : findChildren()) {
if (!child.getState().isAvailable()) {
child.start();
}
} //初始化WebappLoader
if (getLoader() == null) {
WebappLoader webappLoader = new WebappLoader(getParentClassLoader());
webappLoader.setDelegate(getDelegate());
setLoader(webappLoader);
} //实例化contextManager ,用于管理session
Manager contextManager = null;
try {
contextManager = getCluster().createManager(getName());
} catch (Exception ex) {
log.error("standardContext.clusterFail", ex);
ok = false;
}
setManager(contextManager); //1.
//初始化所有Listener实例,
if (ok) {
if (!listenerStart()) {
log.error( "Error listenerStart");
}
}
//2.
try {
// 启动StandardManager,该类管理Session信息
if ((manager != null) && (manager instanceof Lifecycle)) {
((Lifecycle) getManager()).start();
} //启动后台线程, 检查seesion超时
super.threadStart();
} //3. 初始化 application filters
if (ok) {
if (!filterStart()) {
log.error("Error filterStart");
ok = false;
}
} //4.
//加载和初始化标记"load on startup"大于1的Servelet
if (ok) {
loadOnStartup(findChildren());
}

Tomcat初始化监听对象:

监听器分两种LifeCycleListener, EventListener ,如图所示,

参考资料:

https://blog.csdn.net/yangsnow_rain_wind/article/details/80118321


serveltContext

serveltContext标示Tomcat存储当前Web程序的上下文信息,

  1. 每个Engine有多个war包, 每个war包就是一个web应用程序, 每个web应用程序只有一个Context上下文,这就是servletContext.
  2. 每个servletcontext下可以有多个servlet, 每个servlet需要有配置url映射. 每个servlet需要被包装为StandardWrapper类, 存储到servletcontext容器中.
  3. ServletContext 对象是一个为整个 web 应用提供共享的内存,多个servlet实例见可以通过context进行通信.
  4. ServletContext 在tomcat中对应的类是ApplicationContext

参照笔记: https://blog.csdn.net/yangsnow_rain_wind/article/details/80118321


1、spi简单说明
spi,即service privider interface,是jdk为厂商和插件提供的一种解耦机制。
spi的具体规范为:当服务的提供者,提供了服务接口的一种实现之后,在jar包的META-INF/services/目录里同时创建一个以服务接口命名的文件。该文件里就是实现该服务接口的具体实现类。而当外部程序装配这个模块的时候,就能通过该jar包META-INF/services/里的配置文件找到具体的实现类名,并通过反射机制实例化,完成模块的注入。 基于这样一个约定就能很好的找到服务接口的实现类,而不需要再代码里制定。jdk提供服务实现查找的一个工具类:java.util.ServiceLoader

2、spring-web中的具体应用
从servlet3.0开始,web容器启动时为提供给第三方组件机会做一些初始化的工作,例如注册servlet或者filtes等,servlet规范中通过ServletContainerInitializer.onStartup实现此功能。

每个框架要使用ServletContainerInitializer就必须在对应的jar包的META-INF/services 目录创建一个名为javax.servlet.ServletContainerInitializer的文件,文件内容指定具体的ServletContainerInitializer实现类,那么,当web容器启动时就会运行这个初始化器做一些组件内的初始化工作。

一般伴随着ServletContainerInitializer一起使用的还有HandlesTypes注解,通过HandlesTypes可以将感兴趣的一些类注入到ServletContainerInitializerde的onStartup方法作为参数传入。

spring-web的jar定义了一个具体的实现类,SpringServletContainerInitializer,并且在META-INF/services/目录下定义了如下文件org.springframework.web.SpringServletContainerInitializer。

3、SpringServletContainerInitializer

SpringServletContainerInitializer是接口ServletContainerInitializer的实现类,tomcat启动时调用processServletContainerInitializers,通过SPI机制,找到classpath下所有实现ServletContainerInitializers接口的类,然后初始化这个类,并调用此类的接口onStartup.

SpringServletContainerInitializer类上注解为@HandlesTypes(WebApplicationInitializer.class)~,它的作用是将感兴趣的一些类注入到ServletContainerInitializer,并作为参数传给onStartup方法,并后续完成类初始化。

源码如下:

最终ServletContainerInitializers.onStartup方法变成了实现WebApplicationInitializer.onStartup(ServletContext)

4. WebApplicationInitializer

通过实现接口WebApplicationInitializer,在其中可以添加servlet,listener等,在加载Web项目的时候会加载这个接口实现类,从而起到web.xml相同的作用。

其重要的一个实现类是SpringBootServletInitializer

5. SpringBootServletInitializer



事件监听

ServletContextListener:在servlet启动时,获得监听(contextInitialized,contextDestroyed)

ContextLoaderListener: 用来在部署相关Web应用时初始化其上下文环境(initWebApplicationContext, 并放置在servletContext.attr(".root")属性中),在停止退出Web应用时清理其资源

ServletContextListener:

包括两个接口方法:contextInitialized,contextDestroyed,在Web 应用的生命周期中,ServletContext 对象最早被创建,最晚被销毁,常被用于在web容器启动war之前对servlet进行提前配置,

如设置attribute参数到servletContext中。SpringMVC框架中被用来初始化IOC容器等,(ContextLoaderListener类中在contextInitialized方法中初始化initWebApplicationContext(被放在servletContext.attr(".root")属性中))

Filter

Filter(过滤器)可以改变HTTP请求的内容、响应、及header信息,过滤器通常不产生响应或像 servlet 那样对请求作出响应,而是修改或调整到资源的请求,修改或调整来自资源的响应。

当容器接收到传入的请求时,它将获取列表中所有符合该请求的过虑器组成过虑器链(FilterChain),然后通过FilterChain嵌套调用各过虑器的Filter.doFilter()方法(一个过滤器可以使得滤器链调用下一个过滤器),传入ServletRequest 和ServletResponse进行处理。

当滤器链调用完各Filter.doFilter()方法后,会调用相关Servlet.service()方法,从而进行Servlet的处理。注意,Filter.doFilter()可以阻止过滤器链接下来的调用,返回时过滤器负责填充Reponse对象。

过滤器实例移除之前,容器必须先调用过滤器的Filter.destroy()方法。

web.xml中组件加载顺序为:

context-param -> listener -> filter -> servlet(同类则按编写顺序执行)


ApplicationContextInitializer:

ApplicationContextInitializer是Spring框架原有的东西,这个类的主要作用就是在ConfigurableApplicationContext类型(或者子类型)的ApplicationContext做refresh之前,允许我们对ConfiurableApplicationContext的实例做进一步的设置和处理。

ApplicationContextInitializer接口是在spring容器刷新Refresh之前执行的一个回调函数

实际应用:

在一个Springboot应用中,classpath上会包含很多jar包,有些jar包需要在ConfigurableApplicationContext#refresh()调用之前对应用上下文做一些初始化动作,因此它们会提供自己的ApplicationContextInitializer实现类,然后放在自己的META-INF/spring.factories属性文件中,这样相应的ApplicationContextInitializer实现类就会被SpringApplication#initialize发现。

添加方法有三种

1. 启动类里手动增加initializer

@SpringBootApplication
@EnableConfigServer
@EnableDiscoveryClient
public class ConfigServer {
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(ConfigServer.class); // 方法一:添加自定义的 ApplicationContextInitializer 实现类的实例(注册ApplicationContextInitializer)
springApplication.addInitializers(new ApplicationContextInitializer1()); ConfigurableApplicationContext context = springApplication.run(args); context.close();
}
}

2.application.properties添加配置方式

context.initializer.classes = com.springboot.xx.xx.ApplicationPropertiesApplicationContextInitializer

3. 使用spring.factories方式

1. 先定义先定义ApplicationContextInitializer

2、然后在项目下的resources下新建META-INF文件夹,文件夹下新建spring.factories文件

org.springframework.context.ApplicationContextInitializer=com.x.ApplicationContextInitializer1

总结:

ApplicationContextInitializer是Spring留出来允许我们在上下文刷新之前做自定义操作的钩子,若我们有需求想要深度整合Spring上下文,借助它不乏是一个非常好的实现。


网关作用:

在微服务实施之后,各个服务的拆分粒度很小,对于客户端来说,做一个操作可能会涉及到 后端的多个服务组件的调用,那意味着它需要频繁的发起多次访问才能进行数据聚合实现用 户的功能。 如果我们在所有的微服务之前增加一个网关,对于客户端来说它需要做什么功能操作直接调 用网关并且告诉网关所要做的事情即可,网关根据请求的功能对后端的多个服务的数据进行 聚合聚合哦从而减少客户端的调用频次。 并且,由于有了网关的聚合,我们还可以在网关层对请求进行统一鉴权和认证; 包括还可 以实现限流、请求日志统一记录、 灰度发布等等。

Enable 注解不仅仅可以像前面演示的案例一样很简单的实 现多个 Configuration 的整合,还可以实现一些复杂的场 景,比如可以根据上下文来激活不同类型的 bean, @Import 注解可以配置三种不同的 class

1. 第一种就是前面演示过的,基于普通 bean 或者带有 @Configuration 的 bean 进行诸如

2. 实现 ImportSelector 接口进行动态注入
3. 实现 ImportBeanDefinitionRegistrar 接口进行动态注入

@EnableAutoConfiguration 注解的实现原理

在@EnableAutoConfiguration注解内使用到了@import注解来完成导入配置的功能,而EnableAutoConfigurationImportSelector内部则是使用了SpringFactoriesLoader.loadFactoryNames方法进行扫描具有META-INF/spring.factories文件的jar包

自动填充属性
EnableConfigurationProperties
 
 

Spring及tomcat初始化日志的更多相关文章

  1. spring boot Tomcat访问日志

    1.Tomcat设置访问日志 <Host name="localhost" appBase="webapps" unpackWARs="true ...

  2. 从启动日志看Spring IOC的初始化和Bean生命周期

    一.Tomcat中启动IoC容器的日志 启动Tomcat等容器时,控制台每次都打印出一些日志. 最近刚好在研究Spring源码,所以换个角度,从启动日志来简单的看看Spring的初始化过程! 以下是T ...

  3. Spring初始化日志

    Spring启动时的日志: 2013-11-22 14:55:59:319[INFO]: FrameworkServlet 'spring3': initialization completed in ...

  4. Spring Boot 项目初始化

    Spring Boot 项目创建 File->New->New Project->Spring Initializr 勾选 Web Spring Boot 版本选择稳定版,本文选择 ...

  5. Spring Boot 系列:日志动态配置详解

    世界上最快的捷径,就是脚踏实地,本文已收录架构技术专栏关注这个喜欢分享的地方. 开源项目: 分布式监控(Gitee GVP最有价值开源项目 ):https://gitee.com/sanjianket ...

  6. spring + spring mvc + tomcat 面试题(史上最全)

    文章很长,而且持续更新,建议收藏起来,慢慢读! 高并发 发烧友社群:疯狂创客圈(总入口) 奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : 极致经典 + 社群大片好评 < Java 高并发 三 ...

  7. 配置Tomcat的日志系统

    成功配置tomcat的log4j日志系统,格式:HTML+每天以yyyy-mm-dd.log命名的日志文件 一.引言: 实习单位让用log4j配置webapp的日志系统,要求产生的日志文件是html格 ...

  8. Spring 中配置log4j日志功能

    一,添加log4j依赖包 可从官网上下载该依赖包log4j-x.x.xx.jar,下载后 build path,添加依赖包 二,创建 log4j.properties 配置文件 log4j.prope ...

  9. 如何配置Spring Boot Tomcat

    1.概述 Spring Boot Web应用程序默认包含预配置的嵌入式Web服务器.但在某些情况下,我们要修改默认配置以满足自定义要求. 在本教程中,我们将介绍通过application.proper ...

随机推荐

  1. 百度支持链接的nofollow属性吗

    http://www.wocaoseo.com/thread-269-1-1.html 简单明确的一个问题,百度目前支持链接的nofollow属性吗?rel='external nofollow' 复 ...

  2. SEO工程师考试题目

    http://www.wocaoseo.com/thread-201-1-1.html      SEO,全名Search Engine Optimization,其中文名字为'搜索引擎优化' .其英 ...

  3. oeasy教您玩转linux010201持续输出yes

    我们来回顾一下 上一部分我们都讲了什么?

  4. C#转PHP

    官方主页 https://github.com/isukces/cs2php 快速开始 http://www.cs2php.com/how-to-begin.htm#.W2rBhC2B3mI 如何在V ...

  5. java初探(1)之秒杀的业务简单实现

    前言 秒杀的业务场景广泛存在于电商当中,即有一个倒计时的时间限制,当倒计时为0时,秒杀开始,秒杀之后持续很小的一段时间,而且秒杀的商品很少,因此会有大量的顾客进行购买,会产生很大的并发量,从而创造技术 ...

  6. 牛顿迭代法解非线性方程组(MATLAB版)

    牛顿迭代法,又名切线法,这里不详细介绍,简单说明每一次牛顿迭代的运算:首先将各个方程式在一个根的估计值处线性化(泰勒展开式忽略高阶余项),然后求解线性化后的方程组,最后再更新根的估计值.下面以求解最简 ...

  7. IDEA Activiti 画图中文乱码

    画流程图时,如果节点的name填写的是中文,再次打开流程图时中文会显示乱码,如下图: 修改idea64.exe.vmoptions文件,在文件中加上如下代码: -Dfile.encoding=utf- ...

  8. C009:产品格式化输出

    代码: #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { int itemNum; float unitPric ...

  9. 大量数据也不在话下,Spring Batch并行处理四种模式初探

    1 前言 欢迎访问南瓜慢说 www.pkslow.com获取更多精彩文章! Spring相关文章:Springboot-Cloud 前面写了一篇文章<通过例子讲解Spring Batch入门,优 ...

  10. 升级微服务架构5:API网关

    API网关是一个服务器,是系统的唯一入口.从面向对象设计的角度看,它与外观模式类似.API网关封装了系统内部架构,为每个客户端提供一个定制的API.它可能还具有其它职责,如身份验证.监控.负载均衡.缓 ...