Tomcat深度分析(一)

Tomcat深度分析(一)

今天讲下tomcat中Server,StandardServer,Service,StandardService,Catalina,Connector之间的大致的关系,首先我们看下server.xml配置文件:
tomcal6源码中的
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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值