查看tomcat启动配置文件文件都干点啥

& & &在上一章中说道了构造Server,,这次尝试着说一下Tomcat中Server的内容,首先看一下org.apache.catalina.Server接口中定义的方法:
  从这里至少可以看出Server中包含很多Service,通过实现如下接口添加一个新的Service到Services的集合中,或者从集合中删除指定的Service: &
public void addService(Service service);
public void removeService(Service service);
  通过实现如下接口来完成通过service的名称返回Service的操作:  
public Service findService(String name);
  通过实现如下接口来完成获取返回Server中所有Service的操作:  
public Service[] findServices();
  对于Server的网络内容的设置和获取通过如下方法,包括设置地址,端口:  
public int getPort();
public void setPort(int port);
public String getAddress();
public void setAddress(String address);
  获取和指定shotdown命令:
public String getShutdown();
public void setShutdown(String shutdown);
  获取和设置父类的加载器:  
public ClassLoader getParentClassLoader();
public void setParentClassLoader(ClassLoader parent);
  如果设置了Catalina,那么也提供获取和设置的方法:  
public Catalina getCatalina();
public void setCatalina(Catalina catalina);
  通过Server接口至少我们能够得出结论:Server中包含多个Service对象。
  结构如下:
  值得注意的是Server借口继承了Lifecycle接口,
public interface Server extends Lifecycle
  Lifecycle 接口就是来控制Server极其组件的生命周期的,组件实现Lifecycle借口,就可以提供一致化的机制来启动和停止组件。下面看一下&Lifecycle的内容:
  首先是一些常量列表,小插曲,在Tomcat7.0.53中,tomcat在此处的注释有小问题,有兴趣的人可以看一下。  
//组件初始化之前的事件
public static final String BEFORE_INIT_EVENT = "before_init";
//组件初始化之后的事件
public static final String AFTER_INIT_EVENT = "after_init";
//组件start的事件
public static final String START_EVENT = "start";
//组件start之前的事件
public static final String BEFORE_START_EVENT = "before_start";
//组件start之后的事件
public static final String AFTER_START_EVENT = "after_start";
//组件stop之后的事件
public static final String STOP_EVENT = "stop";
//组件stop之前的事件
public static final String BEFORE_STOP_EVENT = "before_stop";
//组件stop之后的事件
public static final String AFTER_STOP_EVENT = "after_stop";
//组件destrop之后的事件
public static final String AFTER_DESTROY_EVENT = "after_destroy";
//组件destrop之前的事件
public static final String BEFORE_DESTROY_EVENT = "before_destroy";
//组件periodic的事件
public static final String PERIODIC_EVENT = "periodic";
  下面就是Lifecycle接口定义的方法列表:
  既然Server中包含的主要对象就是Service,实现了Service就是对外提供服务了,下面在看一下Service的接口定义:
  看了定义的方法之后,很想逐一说明一下,可能会发现问题:
  在Service中添加或移除connector的方法:    
public void addConnector(Connector connector);
public void removeConnector(Connector connector);
& & 说明在每个Service中有多个Connector。
  在Service中添加或移除Executor的方法:   
public void addExecutor(Executor ex);
public void removeExecutor(Executor ex);
  返回所有Connector的方法:  
public Connector[] findConnectors();
  返回所有executor的方法:  
public Executor[] findExecutors();
  设置和获取Container的方法:  
public Container getContainer();
public void setContainer(Container container);
  获取和设置关联的Server对象的方法:  
public void setServer(Server server);
public Server getServer();
  给Service设置获取名称的方法:  
public void setName(String name);
public String getName();
  以上就是Service接口定义的主要方法,得出在Service中包含一个或多个Connector,包含一个或多个Executors和一个Container对象。接着上面的Server---Service图我们可以得出如下关系图: & & & & & & & & & & &
            |---------Connector 
 Server----Service----|
            &|----------Container
  由此可知在Tomcat中的两个重要的组件就是Connector和Container。下面我们着重看一下Connector和Container。
  Container的主要功能是执行从客户端接收的请求,然后给出回应。看一下Container接口定义的方法:
  添加,删除和获取一个子Container:  
public void addChild(Container child);
public void removeChild(Container child);
public Container findChild(String name);
public Container[] findChildren();
  对应的在Container中就应该有设置和获取父Container的方法:  
public void setParent(Container container);
public Container getParent();
  在Container中添加,移除和获取事件监听器:
public void addContainerListener(ContainerListener listener);
public void removeContainerListener(ContainerListener listener);
public ContainerListener[] findContainerListeners();
  在Container中添加,移除和获取属性变更监听器:  
public void addPropertyChangeListener(PropertyChangeListener listener);
public void removePropertyChangeListener(PropertyChangeListener listener);
  触发Container事件:
public void fireContainerEvent(String type, Object data);
  记录指向这个container的请求与响应的日志:  
public AccessLog getAccessLog();
  设置和获取作用在该container及其子container上的方法的延迟时间,单位秒:  
public void setBackgroundProcessorDelay(int delay);
public int getBackgroundProcessorDelay();
  设置和获取相关的集群:  
public void setCluster(Cluster cluster);
public Cluster getCluster();
  设置和获取Loadeer:  
public void setLoader(Loader loader);
public Loader getLoader();
  设置和获取负责管理该Container对应Session pool的Manager对象:  
public void setManager(Manager manager);
public Manager getManager();
  设置和获取Container的名字描述:  
public void setName(String name);
public String getName();
  设置和获取父类的ClassLoader:  
public void setParentClassLoader(ClassLoader parent);
public ClassLoader getParentClassLoader();
  获取Pipeline,负责管理该Container中的相关值:  
public Pipeline getPipeline();
  设置和获取Container的上下文资源:  
public void setResources(DirContext resources);
public DirContext getResources();
  设置和获取启动和停止children container的线程数,可以并行的启动和停止子container:  
public void setStartStopThreads(int startStopThreads);
public int getStartStopThreads();
  Connector类中的变量已经方法实现如下:
  代表一个Container的入口的变量:  
protected Adapter adapter = null;
  实现Servlet的API规则匹配的变量:  
protected Mapper mapper = new Mapper();
  是否允许Trace:  
protected boolean allowTrace = false;
  异步请求的超时时间:  
long asyncTimeout = 10000;
  是否允许DNS查找的标记:  
protected boolean enableLookups = false;
  Mapper监听器:  
protected MapperListener mapperListener = new MapperListener(mapper, this);
  GET和POST方法中,Container解析的最大的参数个数限制(默认值为1000,当设置数值小于0时,表示没有限制):  
protected int maxParameterCount = 10000;
  Container接收POST方法传递的最大数据(默认值为2M):  
protected int maxPostSize = 2 * 1024 * 1024;
  在Container认证时候默认保存的最大数据:(默认值4K):  
  protected int maxSavePostSize = 4 * 1024;
  一系列以逗号分割的,application/x-www-form-urlencoded形式的方法请求体,以什么方式转化成方法的集合:  
protected String parseBodyMethods = "POST";
  通过parseBodyMethods方式确定的方法集合:  
protected HashSet&String& parseBodyMethodsS
  监听请求端口的数量:(默认值为-1):  
protected int port = -1;
  connector对象将请求重定向到那个Server:  
  protected String proxyName = null;
  connector对象请求重定向到server的哪个端口:  
protected int proxyPort = 0;
&  从no-ssl到ssl重定向端口:  
protected int redirectPort = 443;
  通过connector接收到的所有请求的请求方案:  
  protected String scheme = "http";
  是否给每个接收到的请求设置安全连接标记:  
protected boolean secure = false;
  一个String帮助对象:  
protected static final StringManager sm = StringManager.getManager(Constants.Package);
  关联的Service对象:  
protected Service service = null;
  URL编码:  
protected String URIEncoding = null;
  是否用body编码给URL编码:(不明白)  
protected boolean useBodyEncodingForURI = false;
  是否用IP绑定虚拟主机:  
protected boolean useIPVHosts = false;
  下面看一下Connector的构造函数:
  public Connector() {
this(null);
public Connector(String protocol) {
setProtocol(protocol);
// Instantiate protocol handler
Class&?& clazz = Class.forName(protocolHandlerClassName);
this.protocolHandler = (ProtocolHandler) clazz.newInstance();
} catch (Exception e) {
log.error(sm.getString(
"coyoteConnector.protocolHandlerInstantiationFailed"), e);
  Connector的构造函数中第一步是根据protocol名称HTTP/1.1,AJP/1.3或者protocol handler的类的全路径名称,下面是setProtocol方法的代码实现:  
public void setProtocol(String protocol) {
if (AprLifecycleListener.isAprAvailable()) {
if ("HTTP/1.1".equals(protocol)) {
setProtocolHandlerClassName
("org.apache.coyote.http11.Http11AprProtocol");
} else if ("AJP/1.3".equals(protocol)) {
setProtocolHandlerClassName
("org.apache.coyote.ajp.AjpAprProtocol");
} else if (protocol != null) {
setProtocolHandlerClassName(protocol);
setProtocolHandlerClassName
("org.apache.coyote.http11.Http11AprProtocol");
if ("HTTP/1.1".equals(protocol)) {
setProtocolHandlerClassName
("org.apache.coyote.http11.Http11Protocol");
} else if ("AJP/1.3".equals(protocol)) {
setProtocolHandlerClassName
("org.apache.coyote.ajp.AjpProtocol");
} else if (protocol != null) {
setProtocolHandlerClassName(protocol);
  然后根据setProtocol方法设置的protocol handler进行实例化,在setProtocol方法中调用的setProtocolHandlerClassName方法,如下:
  public void setProtocolHandlerClassName(String protocolHandlerClassName) {
this.protocolHandlerClassName = protocolHandlerClassN
  给connector的变量protocolHandlerClassName赋值,然后根据protocolHandlerClassName的值进行实例化。进而赋值给protocolHandler 变量。
  然后是方法createObjectNameKeyProperties,该方法的作用是将请求的address参数拼接成字符串,包括type,port。下面是代码实现:  
protected String createObjectNameKeyProperties(String type) {
Object addressObj = getProperty("address");
StringBuilder sb = new StringBuilder("type=");
sb.append(type);
sb.append(",port=");
int port = getPort();
if (port & 0) {
sb.append(getPort());
sb.append("auto-");
sb.append(getProperty("nameIndex"));
String address = "";
if (addressObj instanceof InetAddress) {
address = ((InetAddress) addressObj).getHostAddress();
} else if (addressObj != null) {
address = addressObj.toString();
if (address.length() & 0) {
sb.append(",address=");
sb.append(ObjectName.quote(address));
return sb.toString();
  创建一个Request对象,Request是一个对Coyote Request的封装,Coyote 这个东西很奇怪,是狼的意思,也不知道为什么外国人喜欢用动物名来给一个技术命名,hadoop,hive,pig等,说Coyote其实是对Socket的一个封装,将Socket的请求和相应封装成一个个Request和Response,具体如何封装,都包涵什么信息等内容以后展开说明:
public Request createRequest() {
Request request = new Request();
request.setConnector(this);
return (request);
  创建一个Response对象:  
public Response createResponse() {
Response response = new Response();
response.setConnector(this);
return (response);
  这里面值得注意的地方就是在request和response中,都有setConnector方法,所有connector是request和response的一个属性。
  下面看方法destroyInternal,这个方法是在LifecycleMBeanBase类中定义的,用来销毁mapperListener,protocolHandler从Service中移除这个Connector对象,代码实现如下:  
protected void destroyInternal() throws LifecycleException {
mapperListener.destroy();
protocolHandler.destroy();
} catch (Exception e) {
throw new LifecycleException
(sm.getString
("coyoteConnector.protocolHandlerDestroyFailed"), e);
if (getService() != null) {
getService().removeConnector(this);
super.destroyInternal();
  设置和获取是否允许Trace方法的执行:  
public void setAllowTrace(boolean allowTrace) {
this.allowTrace = allowT
setProperty("allowTrace", String.valueOf(allowTrace));
public boolean getAllowTrace() {
return (this.allowTrace);
  设置和获取异步请求的过期时间:  
public void setAsyncTimeout(long asyncTimeout) {
this.asyncTimeout= asyncT
setProperty("asyncTimeout", String.valueOf(asyncTimeout));
public long getAsyncTimeout() {
return asyncT
  配置和获取参数,参数这部分在前面的章节已经提到过了:
public void setAttribute(String name, Object value) {
setProperty(name, String.valueOf(value));
public Object getAttribute(String name) {
return getProperty(name);
  剩下的方法都是设置和获取前面定义的变量的值。
  Server的主要接口已经介绍完了,下面看一下一些关键类的实现:
  Server接口的标准实现是StandardServer类,同时StandServer也继承了LifecycleMBeanBase类,看一下StandardServer中几个重要方法的实现:
  找几个重要的方法说明一下:
  向保存Connector的数组中添加新的Connector对象的方法addConnector,代码实现如下:  
public void addConnector(Connector connector) {
synchronized (connectors) {
connector.setService(this);
Connector results[] = new Connector[connectors.length + 1];
System.arraycopy(connectors, 0, results, 0, connectors.length);
results[connectors.length] =
connectors =
if (getState().isAvailable()) {
connector.start();
} catch (LifecycleException e) {
log.error(sm.getString(
"standardService.connector.startFailed",
connector), e);
// Report this property change to interested listeners
support.firePropertyChange("connector", null, connector);
  首先要把Connector和Serice做关联,connector.setService(this),然后将要添加的connector对象添加到保存Connector对象的数组中,此处使用数组,完全是处于效率的考虑。然后查看当前Server对象的状态,如果状态合法的话,那么启动添加的connector对象。然后在更改此Connector的状态。
  返回Connector集合:  
public Connector[] findConnectors() {
return (connectors);
  在Connector集合中移除connector:  
public void removeConnector(Connector connector) {
synchronized (connectors) {
int j = -1;
for (int i = 0; i & connectors. i++) {
if (connector == connectors[i]) {
if (j & 0)
if (connectors[j].getState().isAvailable()) {
connectors[j].stop();
} catch (LifecycleException e) {
log.error(sm.getString(
"standardService.connector.stopFailed",
connectors[j]), e);
connector.setService(null);
int k = 0;
Connector results[] = new Connector[connectors.length - 1];
for (int i = 0; i & connectors. i++) {
if (i != j)
results[k++] = connectors[i];
connectors =
// Report this property change to interested listeners
support.firePropertyChange("connector", connector, null);
  首先遍历Connector集合,找到要移除的connector,如果指定的connector对象状态合法,那么调用该connector的stop方法,然后将指定的connector对象关联的Server置为null,剩下的内容就是整理移除connector对象的Connector集合。
  设置Container方法,该container对象处理Service中所有connector中的请求:  
public void setContainer(Container container) {
Container oldContainer = this.
if ((oldContainer != null) && (oldContainer instanceof Engine))
((Engine) oldContainer).setService(null);
this.container =
if ((this.container != null) && (this.container instanceof Engine))
((Engine) this.container).setService(this);
if (getState().isAvailable() && (this.container != null)) {
this.container.start();
} catch (LifecycleException e) {
if (getState().isAvailable() && (oldContainer != null)) {
oldContainer.stop();
} catch (LifecycleException e) {
// Report this property change to interested listeners
support.firePropertyChange("container", oldContainer, this.container);
  首先是处理这个Server中原有的Container,原来可能有Container也有可能没有,所以要做判断,如果存在的话,解除和Service的关联,然后要处理新的container对象。关联Service,启动Container。
  由于Service中只有一个Container,所以没有移除Container方法,在设置的时候其实是完成了删除更新的操作。
  看一下startInternal方法:  
protected void startInternal() throws LifecycleException {
if(log.isInfoEnabled())
(sm.getString("standardService.start.name", this.name));
setState(LifecycleState.STARTING);
// Start our defined Container first
if (container != null) {
synchronized (container) {
container.start();
synchronized (executors) {
for (Executor executor: executors) {
executor.start();
// Start our defined Connectors second
synchronized (connectors) {
for (Connector connector: connectors) {
// If it has already failed, don't try and start it
if (connector.getState() != LifecycleState.FAILED) {
connector.start();
} catch (Exception e) {
log.error(sm.getString(
"standardService.connector.startFailed",
connector), e);
  该方法就是逐一启动Service中的组件,Container,Executor,Connector。
  stopInternal方法:  
protected void stopInternal() throws LifecycleException {
// Pause connectors first
synchronized (connectors) {
for (Connector connector: connectors) {
connector.pause();
} catch (Exception e) {
log.error(sm.getString(
"standardService.connector.pauseFailed",
connector), e);
if(log.isInfoEnabled())
(sm.getString("standardService.stop.name", this.name));
setState(LifecycleState.STOPPING);
// Stop our defined Container second
if (container != null) {
synchronized (container) {
container.stop();
// Now stop the connectors
synchronized (connectors) {
for (Connector connector: connectors) {
if (!LifecycleState.STARTED.equals(
connector.getState())) {
// Connectors only need stopping if they are currently
// started. They may have failed to start or may have been
// stopped (e.g. via a JMX call)
connector.stop();
} catch (Exception e) {
log.error(sm.getString(
"standardService.connector.stopFailed",
connector), e);
synchronized (executors) {
for (Executor executor: executors) {
executor.stop();
  由这两个方法也能看出来Lifecycle对于个个组件生命周期的一致的生命周期的管理机制。
  其实最开始想用本章说一下如何构建Server,但是觉得还是有必要将Server中的内容展开说明一下,在说如果构建的话可能更好理解。所以就有了这个只是具有说明意义的一节。&
阅读(...) 评论()查看tomcat启动文件都干点啥_百度知道
查看tomcat启动文件都干点啥
提问者采纳
功能非常强大,可以配置你的端口.xml配置文件里面,可以配置启动项目路径,以及启动项目数据库的连接池等在server,可以配置https访问协议
JAVA高级工程师
其他类似问题
为您推荐:
干点的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁6687人阅读
1、首先你要确定你有一个外网ip地址。如果你分配到的是一个局域网IP地址需要经过一系列的转换为外网ip地址,然后继续下面操作。
2、拿到外网IP地址,进行tomcat的server.xml文件的配置。主要进行下面三个地方的配置(本次配置采用的tomcat版本号是7.0.30)
&1)&Connector port=&80& protocol=&HTTP/1.1&& &connectionTimeout=&20000&& & & redirectPort=&8443& /& &将port端口改为80,基于http协议一般是通过80端口访问的,这样可以避免每次都输入8080的麻烦。
&2)&Engine name=&Catalina& defaultHost=&<span style="color:#ff.52.187&& 将defaulHost的localhost改变为你自己的外网ip地址,提供给外面访问。
&3)&Host name=&<span style="color:#ff.52.187& &appBase=&webapps&& & unpackWARs=&true& autoDeploy=&true&&&
& & &Context path=&test& docBase=&D:/SudentManager& reloadable=&true& crossContext=&true&&&/Context& 将Host 里的name改为外网IP地址,同时在该标签里加入Context标签,内容如上,path 代表访问的虚拟路径,docBase代表的是实际项目路径。
经过上面三步的配置,已经实现了服务器的配置。我们就可以启动Tomcat,此时通过ip地址可以直接访问该项目啦。
以上的方法完全适应局域网内使用。
版权声明:本文为博主原创文章,未经博主允许不得转载。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
(8)(18)(25)(2)(5)(1)(2)(6)(2)(2)(3)(4)(10)(15)(13)(3)***CentOS-6 4-minimal版中通过JK-1 2 40整合Ap...
本教程为 李华明 编著的iOS-Cocos2d游戏开发系列教程:教程涵盖关于i......
专题主要学习DirectX的初级编程入门学习,对Directx11的入门及初学者有......
&面向对象的JavaScript&这一说法多少有些冗余,因为JavaScript 语言本......
Windows7系统专题 无论是升级操作系统、资料备份、加强资料的安全及管......}

我要回帖

更多关于 查看tomcat有没有启动 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信