Tomcat深度分析(一)
今天讲下tomcat中Server,StandardServer,Service,StandardService,Catalina,Connector之间的大致的关系,首先我们看下server.xml配置文件:
1.Server节点: StandardServer实现Server接口,内含Service数组,代表顶层Server容器。
2.Service节点: Catalina继承StandardService,StandardService实现Service,代表一个Service节点。
3.Connector节点: StandardService内含Connector数组,代表一个Connector节点。
注意:每个Server的子容器(如:Service,Connector等)都内含一个Server实例指针。
搞清了他们之间的组合和继承关系没有?没有的话我们看下简单的代码:
//顶层容器
public interface Server{
public void setServer(Server server);
}
//顶层容器的实现
public final class StandardServer implements Server {
private int port = 8005; //xml中的Server节点的port属性
private String shutdown = "SHUTDOWN";//xml中的Server节点的shutdown 属性
private Service services[] = new Service[0];
public int getPort() {
return (this.port);
}
public void setPort(int port) {
this.port = port;
}
public String getShutdown() {
return (this.shutdown);
}
public void setShutdown(String shutdown) {
this.shutdown = shutdown;
}
@Override
public void addService(Service service) {
Service results[] = new Service[services.length + 1];
System.arraycopy(services, 0, results, 0, services.length);
results[services.length] = service;
services = results;
}
}
///
//service节点
public interface Service {
public void setServer(Server server);
}
//service节点实现类
public class StandardService implements Service {
private Server server = null; //顶层容器指针
protected Connector connectors[] = new Connector[0];//连接器容器
public void setServer(Server server) {
this.server = server;
}
public void addConnector(Connector connector) {
connector.setService(this);
Connector results[] = new Connector[connectors.length + 1];
System.arraycopy(connectors, 0, results, 0, connectors.length);
results[connectors.length] = connector;
connectors = results;
}
}
// StandardService 的子类
public class Catalina extends StandardService {
public void load() {
//创建xml和具体类的关系
Digester digester = createStartDigester();
digester.push(this);
//解析server.xml节点,实例化个容器,和设置属性值,调用addXXX()方法设置组合关系的指针
digester.parse(inputSource);
}
protected Digester createStartDigester() {
// Initialize the digester
Digester digester = new Digester();
digester.setValidating(false);
digester.setRulesValidation(true);
HashMap<Class, List<String>> fakeAttributes = new HashMap<Class, List<String>>();
ArrayList<String> attrs = new ArrayList<String>();
attrs.add("className");
fakeAttributes.put(Object.class, attrs);
digester.setFakeAttributes(fakeAttributes);
// digester.setClassLoader(StandardServer.class.getClassLoader());
/**
* <pre>
* 创建对象
* 如果Server标签有className属性名就用配置的className的值来实例化Server否则就是org.apache.catalina.core.StandardServer
* </pre>
*/
digester.addObjectCreate("Server", "com.hadluo.xml.StandardServer",
"className");
// 设置Server对象 的 属性值, 调用Server set[xml中的属性名](setPort() setShutdown())
digester.addSetProperties("Server");
// 调用 Server的setServer 方法
digester.addSetNext("Server", "setServer", "com.hadluo.xml.Server");
digester.addObjectCreate("Server/GlobalNamingResources",
"org.apache.catalina.deploy.NamingResources");
digester.addSetProperties("Server/GlobalNamingResources");
digester.addSetNext("Server/GlobalNamingResources",
"setGlobalNamingResources",
"org.apache.catalina.deploy.NamingResources");
digester.addObjectCreate("Server/Listener", null, // MUST be specified
// in the element
"className");
digester.addSetProperties("Server/Listener");
digester.addSetNext("Server/Listener", "addLifecycleListener",
"org.apache.catalina.LifecycleListener");
digester.addObjectCreate("Server/Service",
"org.apache.catalina.core.StandardService", "className");
digester.addSetProperties("Server/Service");
digester.addSetNext("Server/Service", "addService",
"org.apache.catalina.Service");
digester.addObjectCreate("Server/Service/Listener", null, // MUST be
// specified
// in the
// element
"className");
digester.addSetProperties("Server/Service/Listener");
digester.addSetNext("Server/Service/Listener", "addLifecycleListener",
"org.apache.catalina.LifecycleListener");
// Executor
digester.addObjectCreate("Server/Service/Executor",
"org.apache.catalina.core.StandardThreadExecutor", "className");
digester.addSetProperties("Server/Service/Executor");
digester.addSetNext("Server/Service/Executor", "addExecutor",
"org.apache.catalina.Executor");
digester.addRule("Server/Service/Connector", new ConnectorCreateRule());
digester.addRule("Server/Service/Connector", new SetAllPropertiesRule(
new String[] { "executor" }));
digester.addSetNext("Server/Service/Connector", "addConnector",
"org.apache.catalina.connector.Connector");
digester.addObjectCreate("Server/Service/Connector/Listener", null, // MUST
// be
// specified
// in
// the
// element
"className");
digester.addSetProperties("Server/Service/Connector/Listener");
digester.addSetNext("Server/Service/Connector/Listener",
"addLifecycleListener", "org.apache.catalina.LifecycleListener");
// Add RuleSets for nested elements
digester.addRuleSet(new NamingRuleSet("Server/GlobalNamingResources/"));
digester.addRuleSet(new EngineRuleSet("Server/Service/"));
digester.addRuleSet(new HostRuleSet("Server/Service/Engine/"));
digester.addRuleSet(new ContextRuleSet("Server/Service/Engine/Host/"));
digester.addRuleSet(ClusterRuleSetFactory
.getClusterRuleSet("Server/Service/Engine/Host/Cluster/"));
digester.addRuleSet(new NamingRuleSet(
"Server/Service/Engine/Host/Context/"));
// When the 'engine' is found, set the parentClassLoader.
digester.addRule("Server/Service/Engine", new SetParentClassLoaderRule(
parentClassLoader));
digester.addRuleSet(ClusterRuleSetFactory
.getClusterRuleSet("Server/Service/Engine/Cluster/"));
return (digester);
}
}
xml解析重点是Digester框架,具体我就不解析了。下节我们讲下Connector连接器。
老生常谈:深圳有爱好音乐的会打鼓(吉他,键盘,贝斯等)的程序员和其它职业可以一起交流加入我们乐队一起嗨。我的QQ:657455400 表演视频实例:https://v.qq.com/x/page/f0517awx0x4.html