- 浏览: 981493 次
文章分类
- 全部博客 (428)
- Hadoop (2)
- HBase (1)
- ELK (1)
- ActiveMQ (13)
- Kafka (5)
- Redis (14)
- Dubbo (1)
- Memcached (5)
- Netty (56)
- Mina (34)
- NIO (51)
- JUC (53)
- Spring (13)
- Mybatis (17)
- MySQL (21)
- JDBC (12)
- C3P0 (5)
- Tomcat (13)
- SLF4J-log4j (9)
- P6Spy (4)
- Quartz (12)
- Zabbix (7)
- JAVA (9)
- Linux (15)
- HTML (9)
- Lucene (0)
- JS (2)
- WebService (1)
- Maven (4)
- Oracle&MSSQL (14)
- iText (11)
- Development Tools (8)
- UTILS (4)
- LIFE (8)
最新评论
-
Donald_Draper:
Donald_Draper 写道刘落落cici 写道能给我发一 ...
DatagramChannelImpl 解析三(多播) -
Donald_Draper:
刘落落cici 写道能给我发一份这个类的源码吗Datagram ...
DatagramChannelImpl 解析三(多播) -
lyfyouyun:
请问楼主,执行消息发送的时候,报错:Transport sch ...
ActiveMQ连接工厂、连接详解 -
ezlhq:
关于 PollArrayWrapper 状态含义猜测:参考 S ...
WindowsSelectorImpl解析一(FdMap,PollArrayWrapper) -
flyfeifei66:
打算使用xmemcache作为memcache的客户端,由于x ...
Memcached分布式客户端(Xmemcached)
Tomcat的Server初始化及启动过程:http://donald-draper.iteye.com/blog/2327060
Realm域管理:http://www.cnblogs.com/xing901022/p/4552843.html
通过分析Server初始化及启动过程,我们可以看到关键只在Engine的init和start方法
Server中Engine的配置:
下面来看StandardEngine的initInternal和startInternal方法
从上可以看出StandardEngine的initInternal和startInternal方法,实际调用的,
为其父类的initInternal和startInternal,我们来看ContainerBase
从分析ContainerBase,可以得出ContainerBase主要做的工作是,创建后台子容器线程
执行器,执行子容器的启动任务,启动context更新守候线程。
在ContainerBase的startInternal中有这么一句
查看StandardPipeline
在StandardEngine中有构造方法种,初始化
而pipeline是在ContainerBase定义
查看StandardPipeline,处理HTTP请求的Pipeline
//StandardEngineValve,处理请求Valve
//Valve,实际上一个链表,只有后继,没有前驱
总结:
以上分析可以得出,Engine的初始化与启动实际上是委托给ContainerBase,而ContainerBase初始化与启动,主要做的工作是,创建后台子容器线程执行器,执行子容器的启动任务,启动context更新守候线程。ContainerBase拥有一个StandardPipeline,StandardPipeline是处理HTTP请求的管道,在管道内部有很多Valve( Valve, Filter, or Servlet),这些Value是一个只有后继的链,当请求进来的时候,调用invoke(Request request, Response response)处理请求。
Realm域管理:http://www.cnblogs.com/xing901022/p/4552843.html
通过分析Server初始化及启动过程,我们可以看到关键只在Engine的init和start方法
public class StandardService extends LifecycleMBeanBase implements Service { private static final String info = "org.apache.catalina.core.StandardService/1.0"; private String name = null; private static final StringManager sm = StringManager.getManager(Constants.Package); private Server server = null; protected Connector connectors[] = new Connector[0]; private final Object connectorsLock = new Object(); protected ArrayList<Executor> executors = new ArrayList<Executor>(); protected Container container = null; private ClassLoader parentClassLoader = null; @Override protected void initInternal() throws LifecycleException { //注册Service到JMX super.initInternal(); //初始化Container if (container != null) { container.init(); } } @Override protected void startInternal() throws LifecycleException { if(log.isInfoEnabled()) log.info(sm.getString("standardService.start.name", this.name)); //设置Service状态 setState(LifecycleState.STARTING); if (container != null) { synchronized (container) { //启动container container.start(); } } } //Container处理所有请求 public void setContainer(Container container) { Container oldContainer = this.container; if ((oldContainer != null) && (oldContainer instanceof Engine)) ((Engine) oldContainer).setService(null); this.container = container; if ((this.container != null) && (this.container instanceof Engine)) ((Engine) this.container).setService(this); if (getState().isAvailable() && (this.container != null)) { try { //启动Engine this.container.start(); } } } }
Server中Engine的配置:
<Engine name="Catalina" defaultHost="localhost"> <!-- <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/> --> <!-- Use the LockOutRealm to prevent attempts to guess user passwords via a brute-force attack --> <Realm className="org.apache.catalina.realm.LockOutRealm"> <!-- This Realm uses the UserDatabase configured in the global JNDI resources under the key "UserDatabase". Any edits that are performed against this UserDatabase are immediately available for use by the Realm. --> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm> <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> <!-- SingleSignOn valve, share authentication between web applications Documentation at: /docs/config/valve.html --> <!-- <Valve className="org.apache.catalina.authenticator.SingleSignOn" /> --> <!-- Access log processes all example. Documentation at: /docs/config/valve.html Note: The pattern used is equivalent to using pattern="common" --> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host> </Engine>
下面来看StandardEngine的initInternal和startInternal方法
public class StandardEngine extends ContainerBase implements Engine { public StandardEngine() { super(); //设置Http请求Valve pipeline.setBasic(new StandardEngineValve()); /* Set the jmvRoute using the system property jvmRoute */ try { setJvmRoute(System.getProperty("jvmRoute")); } catch(Exception ex) { log.warn(sm.getString("standardEngine.jvmRouteFail")); } // By default, the engine will hold the reloading thread backgroundProcessorDelay = 10; } //默认主机名 private String defaultHost = null; /** * The descriptive information string for this implementation. */ private static final String info = "org.apache.catalina.core.StandardEngine/1.0"; //Engine关联的Service private Service service = null; /** Allow the base dir to be specified explicitly for * each engine. In time we should stop using catalina.base property - * otherwise we loose some flexibility. */ private String baseDir = null; /** * The JVM Route ID for this Tomcat instance. All Route ID's must be unique across the cluster. */ private String jvmRouteId; /** * Default access log to use for request/response pairs where we can't ID the intended host and context. */ private final AtomicReference<AccessLog> defaultAccessLog = new AtomicReference<AccessLog>(); //初始化 protected void initInternal() throws LifecycleException { //获取角色权限 getRealm(); super.initInternal(); } //获取角色权限 public Realm getRealm() { Realm configured = super.getRealm(); // If no set realm has been called - default to NullRealm // This can be overridden at engine, context and host level if (configured == null) { configured = new NullRealm(); this.setRealm(configured); } return configured; } //启动 protected synchronized void startInternal() throws LifecycleException { // Log our server identification information if(log.isInfoEnabled()) log.info( "Starting Servlet Engine: " + ServerInfo.getServerInfo()); // 启动Standard container super.startInternal(); } //添加子容器<Host> public void addChild(Container child) { if (!(child instanceof Host)) throw new IllegalArgumentException (sm.getString("standardEngine.notHost")); super.addChild(child); } }
从上可以看出StandardEngine的initInternal和startInternal方法,实际调用的,
为其父类的initInternal和startInternal,我们来看ContainerBase
public abstract class ContainerBase extends LifecycleMBeanBase implements Container { //子容器Map protected HashMap<String, Container> children = new HashMap<String, Container>(); protected int backgroundProcessorDelay = -1; /** * The container event listeners for this Container. Implemented as a * CopyOnWriteArrayList since listeners may invoke methods to add/remove * themselves or other listeners and with a ReadWriteLock that would trigger * a deadlock. */ //线程安全的容器监听器List protected List<ContainerListener> listeners = new CopyOnWriteArrayList<ContainerListener>(); /** The Loader implementation with which this Container is associated.*/ protected Loader loader = null; /** The Logger implementation with which this Container is associated.*/ protected Log logger = null; /** Associated logger name.*/ protected String logName = null; /** The Manager implementation with which this Container is associated.*/ protected Manager manager = null; /** The cluster with which this Container is associated.*/ protected Cluster cluster = null; //容器名 protected String name = null; /** The parent Container to which this Container is a child.*/ protected Container parent = null; /** The parent class loader to be configured when we install a Loader.*/ protected ClassLoader parentClassLoader = null; /** The Pipeline object with which this Container is associated.*/ protected Pipeline pipeline = new StandardPipeline(this); /** The Realm with which this Container is associated.*/ private volatile Realm realm = null; /** Lock used to control access to the Realm. */ private final ReadWriteLock realmLock = new ReentrantReadWriteLock(); // javax.naming.Context /** The resources DirContext object with which this Container is associated.*/ protected DirContext resources = null; /** The string manager for this package.*/ protected static final StringManager sm = StringManager.getManager(Constants.Package); //当添加子容器时,是否自动启动 protected boolean startChildren = true; /**The property change support for this component. */ protected PropertyChangeSupport support = new PropertyChangeSupport(this); //后台线程 private Thread thread = null; //后台线程完成信号量 private volatile boolean threadDone = false; /** * The access log to use for requests normally handled by this container * that have been handled earlier in the processing chain. */ protected volatile AccessLog accessLog = null; private volatile boolean accessLogScanComplete = false; //处理Container事件线程数 private int startStopThreads = 1; protected ThreadPoolExecutor startStopExecutor; //初始化 protected void initInternal() throws LifecycleException { //LinkedBlockingQueue,线程安全的阻塞队列 BlockingQueue<Runnable> startStopQueue = new LinkedBlockingQueue<Runnable>(); //新建容器事件,线程池执行器 startStopExecutor = new ThreadPoolExecutor( getStartStopThreadsInternal(), getStartStopThreadsInternal(), 10, TimeUnit.SECONDS, startStopQueue, new StartStopThreadFactory(getName() + "-startStop-")); startStopExecutor.allowCoreThreadTimeOut(true); //注册Engine到JMX super.initInternal(); } //启动 protected synchronized void startInternal() throws LifecycleException { //启动loader if ((loader != null) && (loader instanceof Lifecycle)) ((Lifecycle) loader).start(); logger = null; getLogger(); //启动manager if ((manager != null) && (manager instanceof Lifecycle)) ((Lifecycle) manager).start(); //启动cluster if ((cluster != null) && (cluster instanceof Lifecycle)) ((Lifecycle) cluster).start(); //配置Realm Realm realm = getRealmInternal(); if ((realm != null) && (realm instanceof Lifecycle)) ((Lifecycle) realm).start(); //加载resources if ((resources != null) && (resources instanceof Lifecycle)) ((Lifecycle) resources).start(); //获取子容器 Container children[] = findChildren(); List<Future<Void>> results = new ArrayList<Future<Void>>(); for (int i = 0; i < children.length; i++) { //后台线程执行器,执行子容器 results.add(startStopExecutor.submit(new StartChild(children[i]))); } boolean fail = false; for (Future<Void> result : results) { try { result.get(); } catch (Exception e) { log.error(sm.getString("containerBase.threadedStartFailed"), e); fail = true; } } if (fail) { throw new LifecycleException( sm.getString("containerBase.threadedStartFailed")); } // Start the Valves in our pipeline (including the basic), if any //启动请求处理Valves包括basic(StandardEngineValve),这个在Engine构造方法中 if (pipeline instanceof Lifecycle) ((Lifecycle) pipeline).start(); setState(LifecycleState.STARTING); // Start our thread threadStart(); } protected void threadStart() { if (thread != null) return; if (backgroundProcessorDelay <= 0) return; threadDone = false; String threadName = "ContainerBackgroundProcessor[" + toString() + "]"; //新建后台更新上线问线程 thread = new Thread(new ContainerBackgroundProcessor(), threadName); thread.setDaemon(true); thread.start(); } //子容器启动Callable private static class StartChild implements Callable<Void> { private Container child; public StartChild(Container child) { this.child = child; } @Override public Void call() throws LifecycleException { //启动子容器 child.start(); return null; } } /** * Private thread class to invoke the backgroundProcess method * of this container and its children after a fixed delay. */ //后台更新上下文线程 protected class ContainerBackgroundProcessor implements Runnable { @Override public void run() { Throwable t = null; String unexpectedDeathMessage = sm.getString( "containerBase.backgroundProcess.unexpectedThreadDeath", Thread.currentThread().getName()); try { while (!threadDone) { try { Thread.sleep(backgroundProcessorDelay * 1000L); } if (!threadDone) { //获取父容器 Container parent = (Container) getMappingObject(); //获取当前线程ClassLoader ClassLoader cl = Thread.currentThread().getContextClassLoader(); if (parent.getLoader() != null) { cl = parent.getLoader().getClassLoader(); } processChildren(parent, cl); } } } } protected void processChildren(Container container, ClassLoader cl) { try { if (container.getLoader() != null) { Thread.currentThread().setContextClassLoader (container.getLoader().getClassLoader()); } container.backgroundProcess(); } finally { Thread.currentThread().setContextClassLoader(cl); } Container[] children = container.findChildren(); for (int i = 0; i < children.length; i++) { if (children[i].getBackgroundProcessorDelay() <= 0) { processChildren(children[i], cl); } } } } /** * Execute a periodic task, such as reloading, etc. This method will be * invoked inside the classloading context of this container. Unexpected * throwables will be caught and logged. */ //当上下文改变时,重新加载时,上下文,更新到Container @Override public void backgroundProcess() { if (!getState().isAvailable()) return; if (cluster != null) { try { cluster.backgroundProcess(); } } if (loader != null) { try { loader.backgroundProcess(); } } if (manager != null) { try { manager.backgroundProcess(); } } Realm realm = getRealmInternal(); if (realm != null) { try { realm.backgroundProcess(); } } Valve current = pipeline.getFirst(); while (current != null) { try { current.backgroundProcess(); } } current = current.getNext(); } fireLifecycleEvent(Lifecycle.PERIODIC_EVENT, null); } //启动停止,子容器线程工厂类 private static class StartStopThreadFactory implements ThreadFactory { private final ThreadGroup group; private final AtomicInteger threadNumber = new AtomicInteger(1); private final String namePrefix; public StartStopThreadFactory(String namePrefix) { SecurityManager s = System.getSecurityManager(); group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup(); this.namePrefix = namePrefix; } @Override public Thread newThread(Runnable r) { Thread thread = new Thread(group, r, namePrefix + threadNumber.getAndIncrement()); thread.setDaemon(true); return thread; } } /** * Process the specified Request, to produce the corresponding Response, * by invoking the first Valve in our pipeline (if any), or the basic * Valve otherwise. */ //处理HTTP请求 @Override public void invoke(Request request, Response response) throws IOException, ServletException { pipeline.getFirst().invoke(request, response); } //添加子容器权限 @Override public void addChild(Container child) { if (Globals.IS_SECURITY_ENABLED) { PrivilegedAction<Void> dp = new PrivilegedAddChild(child); AccessController.doPrivileged(dp); } else { addChildInternal(child); } } //添加子容器 private void addChildInternal(Container child) { synchronized(children) { if (children.get(child.getName()) != null) throw new IllegalArgumentException("addChild: Child name '" + child.getName() + "' is not unique"); child.setParent(this); // May throw IAE children.put(child.getName(), child); } // Start child // Don't do this inside sync block - start can be a slow process and // locking the children object can cause problems elsewhere try { if ((getState().isAvailable() || LifecycleState.STARTING_PREP.equals(getState())) && startChildren) { //启动自容器 child.start(); } } //产生ADD_CHILD_EVENT事件 fireContainerEvent(ADD_CHILD_EVENT, child); } } /** * Perform addChild with the permissions of this class. * addChild can be called with the XML parser on the stack, * this allows the XML parser to have fewer privileges than * Tomcat. */ protected class PrivilegedAddChild implements PrivilegedAction<Void> { private Container child; PrivilegedAddChild(Container child) { this.child = child; } @Override public Void run() { addChildInternal(child); return null; } } //添加addValve public synchronized void addValve(Valve valve) { pipeline.addValve(valve); } }
从分析ContainerBase,可以得出ContainerBase主要做的工作是,创建后台子容器线程
执行器,执行子容器的启动任务,启动context更新守候线程。
在ContainerBase的startInternal中有这么一句
if (pipeline instanceof Lifecycle) ((Lifecycle) pipeline).start();
查看StandardPipeline
public class StandardPipeline extends LifecycleBase implements Pipeline, Contained { //待子类扩展 protected void initInternal() { // NOOP } //如果Valve实现了LifecycleBase,则启动Valve的startInternal方法 protected synchronized void startInternal() throws LifecycleException { // Start the Valves in our pipeline (including the basic), if any Valve current = first; if (current == null) { current = basic; } while (current != null) { if (current instanceof Lifecycle) ((Lifecycle) current).start(); current = current.getNext(); } setState(LifecycleState.STARTING); } }
在StandardEngine中有构造方法种,初始化
public StandardEngine() { super(); pipeline.setBasic(new StandardEngineValve()); /* Set the jmvRoute using the system property jvmRoute */ try { setJvmRoute(System.getProperty("jvmRoute")); } backgroundProcessorDelay = 10; }
而pipeline是在ContainerBase定义
/** * The Pipeline object with which this Container is associated. */ protected Pipeline pipeline = new StandardPipeline(this);
查看StandardPipeline,处理HTTP请求的Pipeline
public class StandardPipeline extends LifecycleBase implements Pipeline, Contained { /** The basic Valve (if any) associated with this Pipeline.*/ //处理HTTP请求的Basic Valve protected Valve basic = null; /** The Container with which this Pipeline is associated.*/ //关联容器 protected Container container = null; /** Descriptive information about this implementation.*/ protected static final String info = "org.apache.catalina.core.StandardPipeline/1.0"; /** The first valve associated with this Pipeline.*/ //第一个Valve protected Valve first = null; //设置basic-Valve public void setBasic(Valve valve) { // Change components if necessary Valve oldBasic = this.basic; if (oldBasic == valve) return; // Stop the old component if necessary if (oldBasic != null) { if (getState().isAvailable() && (oldBasic instanceof Lifecycle)) { try { ((Lifecycle) oldBasic).stop(); } } if (oldBasic instanceof Contained) { try { ((Contained) oldBasic).setContainer(null); } } } // Start the new component if necessary if (valve == null) return; if (valve instanceof Contained) { ((Contained) valve).setContainer(this.container); } if (getState().isAvailable() && valve instanceof Lifecycle) { try { ((Lifecycle) valve).start(); } } //更新pipeline Valve current = first; while (current != null) { if (current.getNext() == oldBasic) { current.setNext(valve); break; } current = current.getNext(); } this.basic = valve; } //添加Valve @Override public void addValve(Valve valve) { // Validate that we can add this Valve if (valve instanceof Contained) //如果valve是Contained,则设置valve的关联容器 ((Contained) valve).setContainer(this.container); // Start the new component if necessary if (getState().isAvailable()) { if (valve instanceof Lifecycle) { try { //启动valve ((Lifecycle) valve).start(); } } } // Add this Valve to the set associated with this Pipeline //将Valve与PipeLine关联,如果first为null,则Valve关联到first if (first == null) { first = valve; valve.setNext(basic); } else { Valve current = first; while (current != null) { if (current.getNext() == basic) { current.setNext(valve); valve.setNext(basic); break; } current = current.getNext(); } } container.fireContainerEvent(Container.ADD_VALVE_EVENT, valve); } //返回first Valve public Valve getFirst() { if (first != null) { return first; } return basic; } }
//StandardEngineValve,处理请求Valve
final class StandardEngineValve extends ValveBase { public StandardEngineValve() { super(true); } //类信息 private static final String info = "org.apache.catalina.core.StandardEngineValve/1.0"; private static final StringManager sm = StringManager.getManager(Constants.Package); //获取类信息 public String getInfo() { return (info); } //处理HTTP请求 public final void invoke(Request request, Response response) throws IOException, ServletException { //获取Host信息,处理请求 Host host = request.getHost(); if (host == null) { response.sendError (HttpServletResponse.SC_BAD_REQUEST, sm.getString("standardEngine.noHost", request.getServerName())); return; } if (request.isAsyncSupported()) { request.setAsyncSupported(host.getPipeline().isAsyncSupported()); } host.getPipeline().getFirst().invoke(request, response); } //事件推送 public final void event(Request request, Response response, CometEvent event) throws IOException, ServletException { // Ask this Host to process this request request.getHost().getPipeline().getFirst().event(request, response, event); } }
//Valve,实际上一个链表,只有后继,没有前驱
public interface Valve { //-------------------------------------------------------------- Properties /** * Return descriptive information about this Valve implementation. */ public String getInfo(); /** * Return the next Valve in the pipeline containing this Valve, if any. */ public Valve getNext(); /** * Set the next Valve in the pipeline containing this Valve. * * @param valve The new next valve, or <code>null</code> if none */ public void setNext(Valve valve); //---------------------------------------------------------- Public Methods /** * Execute a periodic task, such as reloading, etc. This method will be * invoked inside the classloading context of this container. Unexpected * throwables will be caught and logged. */ public void backgroundProcess(); /** * Perform request processing as required by this Valve. * * An individual Valve <b>MAY</b> perform the following actions, in * the specified order: * [list] * <li>Examine and/or modify the properties of the specified Request and * Response. * <li>Examine the properties of the specified Request, completely generate * the corresponding Response, and return control to the caller. * <li>Examine the properties of the specified Request and Response, wrap * either or both of these objects to supplement their functionality, * and pass them on. * <li>If the corresponding Response was not generated (and control was not * returned, call the next Valve in the pipeline (if there is one) by * executing <code>getNext().invoke()</code>. * <li>Examine, but not modify, the properties of the resulting Response * (which was created by a subsequently invoked Valve or Container). * [/list] * * A Valve <b>MUST NOT</b> do any of the following things: * [list] * <li>Change request properties that have already been used to direct * the flow of processing control for this request (for instance, * trying to change the virtual host to which a Request should be * sent from a pipeline attached to a Host or Context in the * standard implementation). * <li>Create a completed Response [b]AND[/b] pass this * Request and Response on to the next Valve in the pipeline. * <li>Consume bytes from the input stream associated with the Request, * unless it is completely generating the response, or wrapping the * request before passing it on. * <li>Modify the HTTP headers included with the Response after the * <code>getNext().invoke()</code> method has returned. * <li>Perform any actions on the output stream associated with the * specified Response after the <code>getNext().invoke()</code> method has * returned. * [/list] * @exception IOException if an input/output error occurs, or is thrown * by a subsequently invoked Valve, Filter, or Servlet * @exception ServletException if a servlet error occurs, or is thrown * by a subsequently invoked Valve, Filter, or Servlet */ public void invoke(Request request, Response response) throws IOException, ServletException; //推送事件 public void event(Request request, Response response, CometEvent event) throws IOException, ServletException; public boolean isAsyncSupported(); }
总结:
以上分析可以得出,Engine的初始化与启动实际上是委托给ContainerBase,而ContainerBase初始化与启动,主要做的工作是,创建后台子容器线程执行器,执行子容器的启动任务,启动context更新守候线程。ContainerBase拥有一个StandardPipeline,StandardPipeline是处理HTTP请求的管道,在管道内部有很多Valve( Valve, Filter, or Servlet),这些Value是一个只有后继的链,当请求进来的时候,调用invoke(Request request, Response response)处理请求。
发表评论
-
tomcat日志及log4j日志乱码
2017-04-26 15:00 5500Linux系统字符编码:http://www.cnblogs. ... -
SQL盲注的解决方案
2016-10-27 18:35 2570引起SQL盲注的原因:http://www-01.ibm.co ... -
Tomcat的HTTPS配置详解
2016-10-27 16:59 973HTTPS原理详解:http://blog.csdn.net/ ... -
Tomcat的StandardService,Executor初始化与启动
2016-10-13 09:15 1612Tomcat的Server初始化及启动过程:http://do ... -
Tomcat的JioEndPoint,处理HTTP请求
2016-10-12 19:02 1253Tomcat的Connector(Protocol,Coyot ... -
Tomcat的Connector(Protocol,CoyoteAdapterAdapter,AprEndPoint)初始化及请求处理过程
2016-10-12 16:46 1620Tomcat的Server初始化及启动过程:http://do ... -
Tomcat问题集
2016-10-09 17:50 809tcnative-1.dll: Can't load AMD ... -
Tomcat-ConfigContext监听器(Context.xml,web.xml)
2016-09-27 12:59 1984Tomcat的Host初始化(Context,Listener ... -
Tomcat的Host初始化(Context,Listener,Filter,Servlet)
2016-09-27 08:42 1499Tomcat的Engine初始化,启动过程:http://do ... -
Tomcat的Server初始化及启动过程
2016-09-26 11:02 2939Tomcat7,启动过程(BootStrap、Catalina ... -
Tomcat7,启动过程(BootStrap、Catalina)
2016-09-23 19:08 1863Tomcat 系统架构与设计模式,工作原理:http://ww ... -
405 request method post not supported
2016-08-18 18:09 32301.检查链接地址有没有错误 2.看RequestMethod, ... -
apache-tomcat-7.0.67\bin\tcnative-1.dll: Can't load AMD 64-bit .dll on a IA 3
2016-08-12 13:02 1126F:\apache-tomcat-7.0.67\bin\tcn ...
相关推荐
在启动过程中,Tomcat还会进行一系列的初始化操作,例如解析配置文件,创建和配置各个组件,启动监听器和管道等。此外,对于每个Web应用程序,Tomcat还会执行Servlet的加载和初始化,包括读取`web.xml`部署描述符,...
5. **初始化Servlet和Listener**:对于每个Context,Tomcat会扫描并初始化所有的Servlet和Listener。Servlet的生命周期方法如`init()`会被调用。 6. **启动Connector**:Connector开始接受并处理请求。请求被分发到...
理解Tomcat的启动过程和配置对于优化服务器性能和管理Web应用至关重要。本文将深入解析Tomcat的组成部分、启动流程及关键配置文件。 1. Tomcat Server的组成部分 Tomcat的架构由以下几个核心元素构成: 1.1 ...
在这篇文章中,我们将深入探讨Apache Tomcat 7服务器的内部工作机制,重点关注`getServer().init()`方法在服务器初始化过程中的作用。Tomcat作为一款广泛使用的开源Java Servlet容器,它的性能和可扩展性使得它在Web...
通过以上对Tomcat启动流程的解析,我们可以看到Tomcat的启动过程涉及到了多个类和组件的交互与协作。从初始化类加载器、解析配置文件、构建核心组件到最终的启动和服务监听,每一个步骤都至关重要。了解这些细节有助...
2. **生命周期管理**:Tomcat中的每个组件都有其特定的生命周期,包括初始化、启动、暂停、恢复、停止和销毁。了解这些状态转换有助于理解服务的启动和关闭过程。 3. **容器概念**:在Tomcat中,容器是一个可以包含...
Bootstrap是Apache Tomcat服务器的核心启动类,它是Tomcat初始化过程中的关键部分,主要负责加载服务器的配置信息并启动核心服务。在Java应用服务器领域,理解如何通过Bootstrap接口控制Tomcat的启动与关闭对于运维...
为了更好地理解和掌握TOMCAT的工作机制,建议读者结合实际操作进行学习,如下载TOMCAT源码并逐步跟踪其启动过程。 #### 二、Tomcat整体框架结构 TOMCAT的基本框架分为四个主要层次: 1. **Top-Level Elements**:...
在Tomcat7的启动过程中,涉及到很多内部组件的初始化,其中`Digester`是一个重要的工具,用于解析XML配置文件,将XML结构映射为Java对象。本篇文章将深入剖析`Digester`的使用以及它在Tomcat7启动过程中的作用。 `...
- 配置初始化参数。 - 设置会话超时时间。 - 定义错误页面映射。 - **tomcat-users.xml** - **简介**:用于管理用户的登录凭证和权限分配。 - **功能**: - 定义用户及其角色。 - 配置权限。 - **catalina....
1. Bootstrap:启动过程始于Bootstrap类,它加载并初始化Server对象。 2. Server:Server对象包含了全局配置信息,并管理Service组件。 3. Service:Service包含一个或多个Connector(如Coyote)和一个Engine。 4...
- **Bootstrap**: Tomcat启动的入口点,负责初始化Catalina。 - **Catalina**: Tomcat的核心组件之一,主要负责管理整个服务器的生命周期。 - **StandardServer**: 表示一个完整的Tomcat实例,包括所有服务和服务器...
- `Connector`组件通过`Initialize`和`Start`方法控制其初始化和启动过程。 - `ProtocolHandler`接口用于处理实际的网络通信,由多个具体实现类支持不同的协议(如HTTP/1.1、HTTPS等)。 - 例如`...
Lifecycle接口用于统一管理组件的生命周期,包括初始化、启动、停止和销毁等状态的转换。这是Tomcat中的一个重要设计模式,它使得组件的生命周期管理变得清晰和一致。Lifecycle接口由StandardService类实现,...
Tomcat启动过程是怎样的?** - **加载配置文件**:读取`server.xml`、`web.xml`等配置文件。 - **初始化组件**:创建Server、Service、Connector、Engine、Host、Context等组件。 - **启动组件**:按照层次结构...
Server组件负责整个Tomcat的初始化、启动和关闭,它是整个Tomcat的控制中心。 在Tomcat架构中,组件之间的通信和交互是通过事件监听和广播机制来实现的。这种方式同样体现了设计模式中的观察者模式,当一个组件的...
当启动Tomcat时,首先会加载配置文件,然后初始化各个组件。具体步骤如下: 1. **读取配置文件**:读取`conf/server.xml`等配置文件,解析配置信息。 2. **创建Server**:根据配置文件创建Server实例,并初始化...
- **System**:加载`CATALINA_HOME/bin/bootstrap.jar`,初始化Tomcat,同时加载`JAVA_HOME/lib/tools.jar`,提供JSP编译为Servlet的工具类。 - **Common**:加载公共类,对所有Web应用可见,但不推荐Web应用直接...
Tomcat-Bootstrap是Tomcat启动过程中的核心部分,它的主要职责是加载Tomcat的核心类并初始化服务器。这个jar文件包含了用于启动Tomcat服务器的基本Java代码。当我们在命令行中运行`catalina.sh`或`catalina.bat`启动...