server.xml是Tomcat服务器的核心配置文件,它定义了Tomcat服务器的运行参数和容器的配置。下面是对server.xml中一些关键标签的解读:
这是server.xml文件的根元素,它代表了整个Tomcat服务器的实例。
port属性定义了Tomcat的shutdown端口,用于接收关闭服务器的命令。
shutdown属性定义了关闭服务器的命令字符串。
这个标签用于定义服务器启动时要加载的监听器,监听器可以执行一些初始化任务,如日志记录、安全管理等。
这个标签用于定义全局的JNDI资源,如数据源、用户数据库等。
Service代表一个服务,它包含一个Connector和一个Engine,用于处理特定的网络连接。
name属性定义了服务的名称。
Connector定义了服务的网络连接器,它负责监听特定的端口,接收和处理网络请求。
port属性定义了监听的端口号。
protocol属性定义了连接器使用的协议,如HTTP/1.1、AJP/1.3等。
connectionTimeout属性定义了连接超时时间。
redirectPort属性定义了HTTPS重定向的端口号。
Engine是Tomcat容器的顶层组件,它代表了整个服务器的实例。
name属性定义了引擎的名称。
defaultHost属性定义了默认的Host,当请求的域名没有匹配的Host时,将使用默认的Host。
Host代表一个虚拟主机,它与一个特定的域名或IP地址关联。
name属性定义了虚拟主机的域名或IP地址。
appBase属性定义了Web应用的根目录。
unpackWARs属性定义了是否自动解压WAR文件。
autoDeploy属性定义了是否自动部署Web应用。
Context代表一个Web应用的上下文,它定义了Web应用的配置和部署信息。
path属性定义了Web应用的上下文路径。
docBase属性定义了Web应用的文档基础目录。
Valve代表一个容器阀,它用于处理容器级别的请求,如日志记录、错误处理等。
以上是server.xml中一些关键标签的解读,通过配置这些标签,你可以自定义Tomcat服务器的行为和性能。
添加
name:指定虚拟主机的域名或IP地址。
appBase:指定虚拟主机的Web应用目录。
autoDeploy:指定是否自动部署应用目录下的应用。
deployOnStartup:指定在Tomcat启动时是否部署应用目录下的应用。
deployXML:指定是否使用web.xml文件来部署应用。
在Tomcat服务器中,Engine、Host、Context是三个关键的概念,它们构成了Tomcat的容器层次结构,用于管理和组织Web应用。下面分别解释这三个概念:
Engine(引擎):
Engine是Tomcat容器的顶层,它代表一个虚拟的服务器,可以包含多个Host。在Tomcat中,通常只有一个Engine实例,名为Catalina。
Engine负责处理HTTP请求的分发,它将请求分发给相应的Host进行处理。
Engine还负责管理Tomcat的全局生命周期,包括启动和停止等。
Host(主机):
Host代表一个虚拟主机,它与一个特定的域名或IP地址关联。一个Engine可以包含多个Host,每个Host可以有多个Web应用。
Host负责处理特定域名或IP地址的HTTP请求,它将请求分发给相应的Context进行处理。
Host还负责管理Web应用的生命周期,包括加载、卸载和重启等。
Context(上下文):
Context代表一个Web应用的上下文,它是Web应用的容器,负责加载、管理和运行Web应用。
Context负责处理具体的Web应用的HTTP请求,它管理Servlet、过滤器、监听器等Web组件的生命周期。
Context还负责管理Web应用的配置,包括读取web.xml文件、处理注解等。
在Tomcat的容器层次结构中,Engine、Host和Context之间形成了一个树状结构,从Engine到Host再到Context,每一层都负责更具体的任务。这种层次结构使得Tomcat能够灵活地管理多个Web应用,同时支持虚拟主机和多域名的配置。
org.apache.catalina.startup.Catalina#load{
...org.apache.catalina.startup.Catalina#createStartDigester{
//addObjectCreate、addSetProperties、addSetNext三个方法都是添加rule规则
...addObjectCreate->addRule->new ObjectCreateRule{
...begin{
//根据className反射java对象后入栈
...digester.push(instance)...
}...
...end{
//对象出栈,后续操作对象
digester.pop()...
}...
}...
...addSetProperties->addRule->new SetPropertiesRule{
...begin{
//栈顶元素赋值,在使用Digester解析XML文档时,它会根据解析规则创建和管理一个对象栈,用于存储解析过程中创建的Java对象。peek方法允许你在不改变栈状态的情况下查看栈顶的对象。
...digester.peek()...
...IntrospectionUtils.setProperty(top, name, value)...
}...
}...
//Server设置Listener、Service等
...addSetNext->addRule->new SetNextRule{
...end{
//同样栈顶元素开始操作
...Object child = digester.peek(0);
Object parent = digester.peek(1)...
//IntrospectionUtils.callMethod是Apache Commons Lang库中的一个方法,用于通过反射调用Java对象的方法,parent是要调用方法的对象实例
...IntrospectionUtils.callMethod1(parent, methodName,
child, paramType, digester.getClassLoader())...
}...
}....
...digester.addRuleSet(new NamingRuleSet("Server/GlobalNamingResources/"));
//创建Engine对象,设置监听器EngineConfig等
digester.addRuleSet(new EngineRuleSet("Server/Service/"));
//创建Host对象,Engine通过方法addChild设置属性Host等
digester.addRuleSet(new HostRuleSet("Server/Service/Engine/"));
//创建Context对象,设置监听器ContextConfig、Host通过方法addChild设置属性Context等
digester.addRuleSet(new ContextRuleSet("Server/Service/Engine/Host/"));
addClusterRuleSet(digester, "Server/Service/Engine/Host/Cluster/");
digester.addRuleSet(new NamingRuleSet("Server/Service/Engine/Host/Context/"))...
org.apache.catalina.startup.EngineRuleSet#EngineRuleSet{
addRuleInstances{
//方法addObjectCreate、addSetProperties、addRule等
...digester.addObjectCreate(prefix + "Engine",
"org.apache.catalina.core.StandardEngine",
"className");
digester.addSetProperties(prefix + "Engine");
digester.addRule(prefix + "Engine",
new LifecycleListenerRule
("org.apache.catalina.startup.EngineConfig",
"engineConfigClass"));
digester.addSetNext(prefix + "Engine",
"setContainer",
"org.apache.catalina.Engine")...
}
}
}...
//inputStream 此时是 server.xml
inputSource.setByteStream(inputStream);
digester.push(this);
digester.parse->..parse..->scanDocument->..->scanStartElement->emptyElement{
startElement(element, attributes, augs)->org.apache.tomcat.util.digester.Digester#startElement{
//执行rule的begin执行对应的方法其中部分如上三种
...getRules()...
...for rule...
...rule.begin...
}
endElement(element, augs)->org.apache.tomcat.util.digester.Digester#endElement{
...rules = matches.pop()...
...rule.body...
...rule.end...
}
}->scanEndElement{
...endElement{
...endElement{
...rules = matches.pop()...
...for rules->rule.body...
//rule规则里面就有相应的方法其中部分如上三种
...for rules->rule.end...
}...
}...
}
}
//在startInternal这个方法前会setStateInternal->fireLifecycleEvent触发对应状态事件
org.apache.catalina.Lifecycle#start->startInternal->services.start->startInternal->engine.start->startInternal{
//StandardEngine extends ContainerBase
...super.startInternal{
//对于engin得到的是host,对于host得到的是context。异步启动StandardHost,StandardContext(configureStarthild->call->child.start()),调用org.apache.catalina.util.LifecycleBase#start{...startInternal...}。
...Container children[] = findChildren();
List<Future
for (int i = 0; i < children.length; i++) {
results.add(startStopExecutor.submit(new StartChild(children[i])));
}...
// Start our thread
...threadStart()...
}...
}
org.apache.catalina.core.StandardHost#startInternal{
//同上
...super.startInternal{
//得到StandardContext
...Container children[] = findChildren();
List<Future
for (int i = 0; i < children.length; i++) {
//会启动context org.apache.catalina.core.StandardContext#startInternal
results.add(startStopExecutor.submit(new StartChild(children[i])));
}...
//触发ContextConfig事件org.apache.catalina.startup.ContextConfig#configureStart->webConfig
...fireLifecycleEvent(Lifecycle.CONFIGURE_START_EVENT, null)
// Start our child containers, if not already started
for (Container child : findChildren()) {
if (!child.getState().isAvailable()) {
child.start();
}
}...
... // Call ServletContainerInitializers如:org.springframework.web.SpringServletContainerInitializer#onStartup
for (Map.Entry<ServletContainerInitializer, Set<Class<?>>> entry :
initializers.entrySet()) {
...entry.getKey().onStartup(entry.getValue(),
getServletContext())..
}...
//org.springframework.web.context.ContextLoaderListener
...listenerStart->listener.contextInitialized...
}...
}
org.apache.catalina.startup.ContextConfig#webConfig{
...configureContext{
//处理web.xml中的servlet、filter、listen等
//此处的wrapper为解析xml后的servlet:default,jsp,dispathservlet等
...context.addChild(wrapper){
...addChildInternal{
//org.apache.catalina.core.ContainerBase#children
///The child Containers belonging to this Container, keyed by name
//protected final HashMap<String, Container> children = new HashMap<>();
...children.put(child.getName(), child)... //default->org.apache.catalina.servlets.DefaultServlet、jsp->org.apache.jasper.servlet.JspServlet、mvc-test(web.xml中配置的servlet-name)->org.springframework.web.servlet.DispatcherServlet
}...
}...
}...
}