Tomcat source code analysis article (reproduced)

Description: for study, from the original  https://www.cnblogs.com/Jtianlin/p/5041703.html

Tomcat source code analysis (a) - the service starts

1. Tomcat has two main components, connectors and containers, the so-called connector is a http request came, the connector is responsible for receiving the request and then forwarded to the container. That container servlet container, which has many layers, respectively, Engine,

    Host, Context, Wrapper. The largest container Engine, on behalf of a servlet engine, followed by Host, on behalf of a virtual machine, and then Context, on behalf of an application, Wrapper corresponds to a servlet. From the connector

    After transmission over the connection, the container will sequence through the above container, and finally to a particular servlet. It is noted that Engine, Host in both containers is not required. In fact just a simple tomcat connector and container on it,

    But in order to achieve unified management of tomcat connector components and containers, add additional server components (server) and service components (Service) , the reason to add these two things, I personally feel that in order to facilitate unified management and connectors

    The various components of containers. A server may have multiple service, a service comprising a plurality of connectors and a container, of course, there are other things, it is easy to see the following FIG appreciated Tomcat architecture of:

    

2.  a parent component and can contain multiple sub-components, these components are unified management implements the Lifecycle interface. As long as a component starts, then all of his sub-assemblies will follow the start, such as a server started, all its children

    service will follow to start, start the service, all of its connectors and containers also followed the start of the sub-components, so, tomcat To start, just start the server on the list, followed by other components will start

3. General Start Tomcat will be running startup.bat or startup.sh file, in fact, these two documents will eventually call the main method org.apache.catalina.startup.Bootstrap class, the main method is mainly do two things,

    1: define and initialize the tomcat own class loader, 2: invoked by reflection of the process method org.apache.catalina.startup.Catalina;

4.  Process method function is also very simple, 1: If catalina.home and catalina.base two properties is not set to set about, 2: parameters are correct, then it calls the execute method execute method is to simply call the start method,

    Parameters which determine the correct method arguments will set the starting identified as true, so you can start method is called in the execute method, the start method is the key, in which it launched a service to all our Tomcat

The  most important thing here is to createStartDigester (); and ((Lifecycle) server) .start ( ); createStartDigester main role is to help us examples of all service components, including server, service and connect, as for

    How instantiated wait for the next look, start is to start the service instances. File file = configFile (); server.xml file is a new instance, behind the service components are to be the basis of this document

6. Digester is an external jar package inside the class, the main function is to parse xml elements inside the element and generates an object, the attribute of the element is arranged to properties of the object, and the parent-child relationship is formed between the other sibling objects.

    Digester.addObjectCreate ( "Server", "org.apache.catalina.core.StandardServer", "className"); // create a org.apache.catalina.core.StandardServer object here is not actually true

    Create an object, but add a pattern, just behind the object created is based on these patterns and to server.xml, so you can temporarily so understanding. Digester.parse is really to create objects inside the start method (is), is a

    server.xml file stream, digester have just added StandardServer and StandardService and other service components, add the relationship StandardServer and StandardService and StandardService and connectors

    HttpConnector, container StandardHost relationship, so after calling digester.parse (is) method will be used to generate objects and the relationships between them depending on the mode and server.xml file. In this way we will have the server components

    StandardServer objects, but also with its sub-components StandardService objects, etc.

7.  Now that you have the server component object, initialized and then start it, this, tomcat on the realization of starting server components StandardServer. After you start to do more things on, but it is quite clear,

    StandardServer the start code is the key method to start its subcomponents StandardService. StandardService start method with almost StandardServer start method, is to start its connectors and containers, it says a

    Service includes a container and a plurality of connectors

8 . The default connection is HttpConnector, it will call HttpConnector start method. Here's two key categories: HttpConnector and HttpProcessor, they all implement the Runnable interface, HttpConnector

    Http request is responsible for receiving, HttpProcessor responsible for processing requests received by HttpConnector. Note that HttpProcessor have a lot of instances, the maximum you can have a maxProcessor, initialization is 20. Therefore,

    threadStart method starts a background thread to receive http connection

9 . In this way, it will start HttpConnector background thread, its run method continuous cycle, mainly to create a ServerSocket listening port to wait for connections. After serverSocket been waiting for a connection, get connected to HttpProcessor

    Examples of processor to handle, serverSocket the loop continues to listen, as to how to deal with the specific processor, there is a lot to say, I will not speak here.

 

Analysis Tomcat source (b) - connection processing

1.   On a HttpConnector already started a thread, and also launched a fixed number of HttpProcessor threads. Wherein after HttpConnector to wait for http connections, to give a http connection HttpProcessor

     Thread to handle. In particular took a look at how to get connected HttpConnector is available, as well as how to deal with HttpProcessor

2. Here it is critical socket = serverSocket.accept (); and processor.assign (socket); in circulation inside, serverSocket.accept (); http request is responsible for receiving and then assigned to socket, to which a last processor

    deal with. Here processor does not need to wait until re-instantiated, but already has a number of processor when HttpConnector initialization. httpConnector which holds a stack that contains HttpProcessor objects needed

    When he wants out.

3. Next the processor.assign (socket); Remember this method is asynchronous, no need to wait HttpProcessor be processed, so HttpConnector to uninterrupted incoming Http requests

4.  Obviously, it's the beginning of a run method is to call the above await method to wait (since the beginning of available variable false), so HttpProcessor will block until there is a thread to wake it up. When called from the HttpConnector

    processor.assign (socket), socket will pass this HttpProcessor object and set available to true, call notifyAll () wakes up the processor threads to handle the socket. At the same time, the await method available again

    Set to false, so went back to the initial state, that can be re-accepted socket. Here is the method of treating Process socket (socket), two major acts, 1: parsing the socket, i.e. parses http request includes a request method, protocol request to

    Filling request, response object is (are not very familiar with the request servlet and jsp development frequently used, response objects is from here). 2: Incoming request, response object to the container and HttpConnector bound, let container

    Call invoke methods for processing. 

The request will parse ×× inside those methods, response to initialize the object, and then call the invoke method for processing container, so far, http request over the connection has been forwarded to the perfect container handling, container remaining question is to the final turn

    Which question servlet or jsp handed. Earlier we know that a connection is connected with a container, the container will have a large level or a plurality of sub-containers, the container is the smallest the Wrapper, the servlet corresponding to a, here we just know the request

    It determines the final route will choose which wrapper, wrapper eventually calls the servlet. Problem at least a start has been made to understand.

 

Tomcat source code analysis (three) - Connector is how associated with the container?

This article To understand a problem, we know that a link is associated with a container, the container with the linker is on when associated?

1.  Before understand the problem first look Digester library, which simply means that parse xml file, there are two concepts: patterns and rules, the so-called model is a xml label rule is experiencing a xml tag needs What to do, look at his three main methods:

    addObjectCreate (String pattern, String className, String attributeName) according to the mode pattern instantiate an object className

    addSetProperties (String pattern) set the properties of this pattern

    addSetNext (String pattern, String methodName, String paramType) add a relationship between mode, call the parent mode

    The above may be difficult to understand, to see how the tomcat Digester used in the method org.apache.catalina.startup.Catalina.createStartDigester () is, in the use of this method, there Digester to parse the server.xml file

2.  encounter label Server / Service / Connector time (here simplifying the argument, it should be sub-sub-label under the label Service label Server Connector, a bit hard to pronounce), instantiate HttpConnector, then it's on a parent container StandardService

    Under call addConnector, so put down the linker HttpConnector added to the container StandardService

3.  adding a linker to the connector StandardService array of connectors, and then on the associated container StandardService

4.  When we call digester.addRuleSet (new EngineRuleSet ( "Server / Service /")); method, Digester will automatically call to addRuleInstances method EngineRuleSet class, it is nothing more than add a variety of patterns and rules in which method,

    According to the above rule is added, it is easy to know where has added a StandardEngine objects (container), and then add a relationship with StandardService StandardEngine in the primary mode of the mode of Server / Service, namely by setContainer

    Method to add StandardService container inside.

5.  The container is provided to the lower StandardService, the "sync block" at the associated container on the linker and, thus, is associated to the container and on the linker.

 

Tomcat source code analysis (four) - container processing link of chain of responsibility pattern

1.  connector.getContainer () to get the container should be StandardEngine (in fact, should be obtained from the server.xml configuration file, where the first assumption is StandardEngine), StandardEngine not invoke methods, and it inherits

     ContainerBase (virtually all containers are inherited from ContainerBase, there are a number of public methods and properties of container in ContainerBase class)

by a code known ContainerBase invoke method is transmitted to the Pipeline, the Pipeline invoke method call. Pipeline here to say what the class, this class is a conduit, each conduit comprising a plurality of class Pipeline valves, valves are

    Class that implements the interface Valve, Valve interface declares invoke methods. The concept of pipes and valves with servlet programming inside the filter mechanism is very like, like pipe filter chain, valve is like a filter. However, there is a basic idea pipeline valve,

    The so-called base valve in the pipe when the pipe is all the valves are common to call after the completion of the call. Whether ordinary valve or valves basis, have achieved Value interface, also inherited from the abstract class ValveBase. In the tomcat, when we called pipeline

    invoke method, the pipe will invoke method call it inside the valve sequence.

wherein the pipe is StandardPipelineValveContext an internal class, the role is to help the pipe inner classes calling sequence valve invoke method Value

    Method invokeNext inner classes StandardPipelineValveContext by a pipeline to access the next array Pipeline stage variable used to save the current local variables to access the first several valves, pipes Valves save all valves in the valve ordinary call

    invoke method is based StandardPipelineValveContext itself will pass into the interior, so that we can call the ordinary method invokeNext valve so as to access the next valve invoke method

4.  invoke method of this valve, achieved invoke method call the next pass through the valve to come StandardPipelineValveContext (ValveContext implements interface) invokeNext method. Then simply print the ip address of the request.

    After the last look invokeNext StandardPipelineValveContext method, the complete array of valves of the valve the valve ordinary call, start calling the invoke method based basic valve, where said first base valve initialization, each class constructor has a container

    Initializes the base valve. I.e., has been added to the configuration of the container when the valve base into the pipeline conduit, so that the StandardPipelineValveContext invokeNext method can call invoke in the base of the valve, when

    basic.invoke (request, response, this); into the base valve StandardEngineValve

5.  In the valve StandardEngineValve StandardEngine basis, the invoke method is called the sub-tank (sub-tank is here StandardHost), remember the beginning connector.invoke (request, response)

    (I.e. invoke method StandardEngine) smoothly transferred to the now invoke method StandardHost child containers, into a StandardHost.invoke (request, response). It can be speculated StandardHost will be passed to it

    The sub-tank, and finally passed to the smallest container StandardWrapper invoke method, and then invoke method call basis of StandardWrapper StandardWrapperValue valve, since the container is the smallest StandardWrapper,

    It can not be passed to invoke a method other containers, and that its invoke method to do what? Mainly do two things, 1: Create a filter chain and 2: assign a servlet or jsp

6.  Here is not the first concern jsp, just look at servlet, by servlet = wrapper.allocate (); StandardWrapper method of entering allocate, allocate mainly call loadServlet method,

    Method loadServlet tomcat class with their class loader instantiates a servlet object and call the service and the servlet's init method. Having thus passed to the request (service or the jsp) service method of the servlet,

    The entire process requests to the end here, and the rest is returned to the client up.

 

Analysis Tomcat source (V) - servlet container connected to the mapping process

In this paper the problem to be solved: a http request over specific servlet container is how to know which to choose?

1.  a Context container that a web application, a Wrapper represent a servlet container, so the above issues can convert how to select from the Context servlet container, the answer is mapper. Mapper Mapper interface is realized

    Category, action is based on the connection request (mainly protocol and path) to select the next container can be seen as a hash table to select a specific key field value based, interfaces Mapper

2.  In Tomcat source (4) Analysis - Processing Chain of Responsibility pattern linking the container is already known, the invoke method request for connection arrives StandardContext container, which will eventually reach the invoke method StandardContextValue valve, in this

    invoke a method has such a code. This code indicates the container calls the method to map the request to map the specific wrapper, meaning that, according to the connection request requesting selected wrapper. The above map will call the parent ContainerBase

    The map way to find specific mapper, as this is how the mapping and container association on, please refer to the specific  Tomcat source code analysis (three) - Connector is how associated with the container? This article, roughly the same principle. StandardContext container

    The key has a standard implementation class StandardContextMapper mapper, so the final calls to map mapper StandardContextMapper method, this method is to select the servlet

3. The  points in the pattern 4 matches (exact match, prefix match, expanded match, matching default) warpper selected, the key code is the name = context.findServletMapping and wrapper = (Wrapper) context.findChild (name ); where

    Face context are StandardContext. context.findServletMapping is to find the servlet name based on pattern matching, context.findChild find specific wrapper according servlet name. findServletMapping approach is

    Simply to get inside servlet name in a HashMap

 

 

Tomcat source code analysis (six) - logger and internationalization

1.  As long as there can be realized a Logger own logger, wherein setContainer logger is associated with the particular container, setVerbosity level setting is the log, log specific logging function. FATAL, ERROR, WARNING,

    INFORMATION, DEBUG logging on behalf of five levels, will be able to understand the meaning of the word see. Here mainly explain FileLogger class, which is one of the Tomcat logger, put it in a log file, start FileLogger

    Methods and closed just starting a life cycle events, do not do other things

 

Tomcat source code analysis (seven) - a single start / close mechanism (life cycle)

1. Tomcat There are many components to a component inevitably start a little trouble. Since the containment relationship is Tomcat Catalina-> Server-> Service-> container / connectors / log, etc., may then be responsible for on / off by its parent component sub-assembly,

    So long as the start Catalina, others are automatically started. This single startup and shutdown mechanisms are realized by implementing the interface Lifecycle

2.  When the time component implements the Lifecycle interface, the parent component starts, ie start method is called, as long as the sub-components also start method is called the parent component of the start of the methods can be (only achieve a unified interface to achieve unified call Lifecycle, as calls

    Mode: (Lifecycle) .start subassembly ())

3.  the key ((Lifecycle) server) .start ( ); this will start when the start of the Catalina Server, look StandardServer start method

    Mainly do two things, 1: sending lifecycle events to the listener; 2: Promoter Component services (For related how the server services See previous articles, are no longer the future on how the associated problems).

4.  Here to diverge a bit, talk about the listeners, lifecycle tool is an instance of a class LifecycleSupport, each component has such a tool category, class role of this tool is to help manage listeners on the component, including the addition of listener and mass

    Event to listener

The  look constructor, passing a Lifecycle, because each component Lifecycle achieved, so this is actually a component passed, i.e., each component has associated with it a LifecycleSupport, when the component to be added in when a listener,

    Actually add tools LifecycleSupport of a listener array of listeners, when you want to send the event of a component life cycle tools will traverse the array of listeners, and then one by one to send event. Here we need to achieve

    His listener class and add the components we need to listen them. Implement listener classes on the line as long as the interface to achieve LifecycleListener

6.  We need to do is implement LifecycleListener interface has its own listeners, write something after listening to their own events to do in lifecycleEvent method, and then add the component to listen on the line, such as when we look at StandardServer

    If started, the start method of the above has a StandardServer this code: lifecycle.fireLifecycleEvent (START_EVENT, null); i.e. StandardServer start sending events to the listener associated with it. Next back

    The beginning, when the server starts, then starts its subcomponents-Service, i.e. StandardService call start method, this method with almost StandardServer start method, but the connectors and the container start, start the connector

    Methods In the previous article already mentioned, mainly launched n processors HttpProcessor components. Top-level container is StandardEngine, its start method only calls the start method of the parent class ContainerBase

    It started all of the other components of Tomcat, including loader, mappers, loggers, pipes, etc., can also be seen from here, they have achieved Lifecycle interface. Close unified with the logic of almost uniform start, do not say here.

 

Tomcat source code analysis (eight) - loader (loader)

1.  the Tomcat is to use this method. jdk suggested that we implement your own class loader when the rewrite findClass method is not recommended to rewrite loadclass method because loadclass method ensures that the father commissioned ClassLoader class loading mechanism,

    If you override this method, we need to implement means to realize his father commissioned mechanism loadclass overridden method

2.  When all the parent class method findClass are not loaded, it will be called findClass method that calls to our own class loader

3.  In the realization of our own class loader, defineClass method is the real class loaded into the jvm, defineClass is inherited from ClassLoader, the array of bytes that represent classes loaded into the jvm converted into a class.

4.  Our own implementation of the class loader class loader with the system are not essentially different, the biggest difference is the different load paths, the system class loader will load path specified in the environment variable CLASSPATH and jvr documents, our own classes Loader

    You can define the class file path to their own needs to load. Also a class file, use the system class loader, and custom loader loaded into the jvm after class structure is no different, but their access to is not the same, the resulting object because different loader

    It will be different. Of course, our own class loaders can have more flexibility, such as the a class file (actually a binary file) encrypted (simple encryption put 0 and 1 interchanged), the system class loader will not load, you need to define our own

    Decryption class loader to load the class file.

5.  Now let's look at the initial Tomcat class loader, why Tomcat have their own class loader . Well, if not their own class loader, we know that, in a Tomcat can be deployed in many applications, If all classes by

    System class loader to load, then deployed on the Tomcat application can access the class A B application, so that between the A and B applied to the application of no security. Another reason is because Tomcat need to implement auto-reload type, so it

    We need to implement your own class loader. Tomcat load is achieved WebappLoader class Loader interface is a component of Tomcat, in order to achieve unified management Lifecycle interface, start method is called when you start, the start

    The main method to do the following things:

    1: Create a real class loader to load it and set the path, call the method createClassLoader

    2: Start a thread to support auto-reload, call the method threadStart

6.  In the createClassLoader method instantiates a class loader WebappClassLoader true, the code is very simple. WebappClassLoader is Tomcat class loader, it inherits

    URLClassLoader (This class is the grandson of ClassLoader class) class. FindClass and rewrite the loadClass method. findClass method Tomcat related class does not load, just look for the already loaded class

    This class has not been loaded, the specific load is achieved in the loadClass method overridden, it can be seen from the above discussion of java, rewrite the loadClass method would mean the loss of the father commissioned class loader mechanism, needs its own

    Father commissioned to implement the mechanism.

7. The  above code is very long, but realized the Tomcat own class loading mechanism, specific rules are loaded:

    1: Since all the classes are already loaded cached, so check local cache

    2: If there is no local cache, the cache is checked, i.e. call findLoadedClass ClassLoader class () method;

    3: If two buffers are not, the system is used for class loading, to prevent Web application class overrides class J2EE

    4: If the open flag delegate (indicate whether the agent to the parent loader to load), or to be loaded class belongs to the package triggers the package name, then call the parent class loader to load, if the parent class loader is null, the system class loader

    5: Load related classes from the current repository

    6: If the repository is not related to the current class, and the flag delegate is false, then call the parent class loader to load, if the parent class loader is null, the system class loader (4 can only be performed with 6 a step)

8. A  check system ClassLoader, so WEB-INF / lib and WEB-INF / classes or class definitions {tomcat} / in libs not cover the underlying JVM able to locate the definition (for example, not defined by the bottom of an alternative java.lang.Integer implementation  

 

Tomcat source code analysis (nine) - Session Management

1. JSESSIONID is a unique identification number used to identify the server Session, that the cookies used to identify the client, the client and server through this JSESSIONID to-one correspondence. It should be noted here that already contains Cookie

    JSESSIONID, and it can be understood as JSESSIONID is a Cookie in a property.

2.  I assume that once a client connects to explain my understanding of one of these three concepts:

    Http connection itself is stateless, that is, before a connection is not initiated after the first with any relationship, belong to two separate connection request, but need to have Internet access are basically state that the server needs to know the connection request twice It is not the same

    A person visit. Time as you browse Taobao time, put something to the cart, and then opening another page of hope in this commodity page inside the cart as well as the last added to the shopping cart of goods. That server will know that Taobao

    Two visits are the same for client access.

    The client first request to a server connection that is not accompanied by anything, no Cookie, no JSESSIONID. After the server receives a request, it checks the request has no JSESSIONID pass over or Cookie,

    If you do not JSESSIONID and Cookie, the server creates a Session, and generate a return with the Session JSESSIONID associated to the client, the client will save this JSESSIONID, and with that generate a

    JSESSIONID associated Cookie, when the second request, will the Cookie (includes JSESSIONID) sent together to the server, the server found that the request has been Cookie, will be removed from JSESSIONID, then

    According to this JSESSIONID find the corresponding Session, that such Http put into a non-connected state stateful connections. But sometimes the browser (ie client) disables Cookie, Cookie is we know through Http request header

    A cookie field pass past, if disabled, it will not be this value, JSESSIONID Cookie can not pass through the server-side, of course, we have other solutions, url rewriting and hidden form, url rewrite is to

    JSESSIONID pass past comes back url. Is a hidden form when the form is submitted incoming a hidden field JSESSIONID. Both methods can pass the JSESSIONID past.

3.  Code mainly cookie from the http request header field is obtained and provided to the sessionid reqeust JSESSIONID no not provided. Such clients JSESSIONID (cookie) spread to tomcat, tomcat

    JSESSIONID of the value assigned to the request. In this request on the uniqueness of the Tomcat identified.

4.  the Session only useful applications, Session two applications can not be shared in general, in a Context represents a Tomcat application, so an application should have its own the Session, Tomcat using Manager to manage various applications

    The Session, Manager is a component, is one to one relationship with Context, please refer to how the associated Tomcat source code analysis (a) - the service starts , a similar method. Manager standard implementation is StandardManager,

    By its unified management Context Session object (standard implementation is StandardSession), can guess, StandardManager Session object will be able to create and find the application associated with it in accordance with JSESSIONID

    Session object. In fact StandardManager does have such an approach, but does not have the two methods StandardManager

5. Session is generated at what time? Think about it, when we write a servlet, if need to use Session, will use request.getSession (), this method will eventually call to the HttpRequestBase

    getSession () method , so here's an important point: Session is not in the client's first visit will be generated on the server side, but on the server side (usually the servlet) using the request method was invoked getSession

     Generated. But by default, jsp page will call request.getSession (), that is, the property jsp page <% @ page session = "true"%> The default is true, it will call compiled into a servlet

     request.getSession (). So as long as access jsp page, usually creates a session on the server side. But in the servlet needs to display call getSession (), of course, in the case of use of the session.

 

Tomcat source code analysis (x) - deployer

1.  In the Tomcat world, a representative of a container Host virtual machine resources, Context container application on behalf of a so-called deployer is the ability to add a component to the Host Context container vessel. Obviously, a Host

    Container should have a deployment component.

2.  In the Catalina createStartDigester () method, the instance is added to a HostConfig StandardHost vessel. HostConfig LifecycleListener class implements an interface, which means that it is a listener class,

    You can listen to the component lifecycle events

3.  If you start listening to StandardHost container started, call the start method

4.  ((Deployer) Host) .install (the contextPath, URL); StandardHost method calls to install, and then install method StandardHostDeployer by StandardHost transferred to,

    StandardHostDeployer is a helper class, help to achieve StandardHost publishing application that implements the Deployer interface to see if it's install (URL config, URL war) method (it has two install methods, respectively

    To publish applications in different ways above

Guess you like

Origin www.cnblogs.com/123-shen/p/11445832.html