tomcat源码分析(一)初始化---Debug方式

来源:互联网 发布:多维数组 数组的数组 编辑:程序博客网 时间:2024/04/29 05:03

引用网址:

http://tomcat.apache.org/tomcat-6.0-doc/architecture/startup/serverStartup.txt

http://tomcat.apache.org/tomcat-6.0-doc/architecture/startup/serverStartup.pdf

Tomcat启动时序第一步:初始化
类: org.apache.catalina.startup.Bootstrap
 1     /** 2      * Initialize daemon. 3      */ 4     public void init() 5         throws Exception 6     { 7  8         // Set Catalina path 9         setCatalinaHome();10         setCatalinaBase();11 12         initClassLoaders();13 14         Thread.currentThread().setContextClassLoader(catalinaLoader);15 16         SecurityClassLoad.securityClassLoad(catalinaLoader);17 18         // Load our startup class and call its process() method19         if (log.isDebugEnabled())20             log.debug("Loading startup class");21         Class startupClass =22             catalinaLoader.loadClass23             ("org.apache.catalina.startup.Catalina");24         Object startupInstance = startupClass.newInstance();25 26         // Set the shared extensions class loader27         if (log.isDebugEnabled())28             log.debug("Setting startup class properties");29         String methodName = "setParentClassLoader";30         Class paramTypes[] = new Class[1];31         paramTypes[0] = Class.forName("java.lang.ClassLoader");32         Object paramValues[] = new Object[1];33         paramValues[0] = sharedLoader;34         Method method =35             startupInstance.getClass().getMethod(methodName, paramTypes);36         method.invoke(startupInstance, paramValues);37 38         catalinaDaemon = startupInstance;39 40     }
工作流程如下:a) Set up classloaders commonLoader (common)-> System LoadersharedLoader (shared)-> commonLoader -> System LoadercatalinaLoader(server) -> commonLoader -> System Loaderb) Load startup class (reflection)org.apache.catalina.startup.CatalinasetParentClassloader -> sharedLoaderThread.contextClassloader -> catalinaLoaderc) Bootstrap.daemon.init() complete第二步: 处理命令行参数 (start, startd, stop, stopd)类: org.apache.catalina.startup.Bootstrap (假定命令为start)
        try {            String command = "start";            if (args.length > 0) {                command = args[args.length - 1];            }            if (command.equals("startd")) {                args[0] = "start";                daemon.load(args);                daemon.start();            } else if (command.equals("stopd")) {                args[0] = "stop";                daemon.stop();            } else if (command.equals("start")) {                daemon.setAwait(true);                daemon.load(args);                daemon.start();            } else if (command.equals("stop")) {                daemon.stopServer(args);            } else {                log.warn("Bootstrap: command \"" + command + "\" does not exist.");            }        } catch (Throwable t) {            t.printStackTrace();        }

 

工作流程如下: a) Catalina.setAwait(true);b) Catalina.load()
 1     public void load() { 2  3         long t1 = System.nanoTime(); 4  5         initDirs(); 6  7         // Before digester - it may be needed 8  9         initNaming();10 11         // Create and execute our Digester12         Digester digester = createStartDigester();13 14         InputSource inputSource = null;15         InputStream inputStream = null;16         File file = null;17         try {18             file = configFile();19             inputStream = new FileInputStream(file);20             inputSource = new InputSource("file://" + file.getAbsolutePath());21         } catch (Exception e) {22             ;23         }24         if (inputStream == null) {25             try {26                 inputStream = getClass().getClassLoader()27                     .getResourceAsStream(getConfigFile());28                 inputSource = new InputSource29                     (getClass().getClassLoader()30                      .getResource(getConfigFile()).toString());31             } catch (Exception e) {32                 ;33             }34         }35 36         // This should be included in catalina.jar37         // Alternative: don't bother with xml, just create it manually.38         if( inputStream==null ) {39             try {40                 inputStream = getClass().getClassLoader()41                 .getResourceAsStream("server-embed.xml");42                 inputSource = new InputSource43                 (getClass().getClassLoader()44                         .getResource("server-embed.xml").toString());45             } catch (Exception e) {46                 ;47             }48         }49         50 51         if ((inputStream == null) && (file != null)) {52             log.warn("Can't load server.xml from " + file.getAbsolutePath());53             return;54         }55 56         try {57             inputSource.setByteStream(inputStream);58             digester.push(this);59             digester.parse(inputSource);60             inputStream.close();61         } catch (Exception e) {62             log.warn("Catalina.start using "63                                + getConfigFile() + ": " , e);64             return;65         }66 67         // Stream redirection68         initStreams();69 70         // Start the new server71         if (server instanceof Lifecycle) {72             try {73                 server.initialize();74             } catch (LifecycleException e) {75                 log.error("Catalina.start", e);76             }77         }78 79         long t2 = System.nanoTime();80         if(log.isInfoEnabled())81             log.info("Initialization processed in " + ((t2 - t1) / 1000000) + " ms");82 83     }

 standardServer.java

 1     public void initialize() 2         throws LifecycleException  3     { 4         if (initialized) { 5                 log.info(sm.getString("standardServer.initialize.initialized")); 6             return; 7         } 8         lifecycle.fireLifecycleEvent(INIT_EVENT, null); 9         initialized = true;10 11         if( oname==null ) {12             try {13                 oname=new ObjectName( "Catalina:type=Server");14                 Registry.getRegistry(null, null)15                     .registerComponent(this, oname, null );16             } catch (Exception e) {17                 log.error("Error registering ",e);18             }19         }20         21         // Register global String cache22         try {23             ObjectName oname2 = 24                 new ObjectName(oname.getDomain() + ":type=StringCache");25             Registry.getRegistry(null, null)26                 .registerComponent(new StringCache(), oname2, null );27         } catch (Exception e) {28             log.error("Error registering ",e);29         }30 31         // Initialize our defined Services32         for (int i = 0; i < services.length; i++) {33             services[i].initialize();34         }35     }

standardService.java

    public void initialize()            throws LifecycleException    {        // Service shouldn't be used with embeded, so it doesn't matter        if (initialized) {            if(log.isInfoEnabled())                log.info(sm.getString("standardService.initialize.initialized"));            return;        }        initialized = true;        if( oname==null ) {            try {                // Hack - Server should be deprecated...                Container engine=this.getContainer();                domain=engine.getName();                oname=new ObjectName(domain + ":type=Service,serviceName="+name);                this.controller=oname;                Registry.getRegistry(null, null)                    .registerComponent(this, oname, null);                                Executor[] executors = findExecutors();                for (int i = 0; i < executors.length; i++) {                    ObjectName executorObjectName =                         new ObjectName(domain + ":type=Executor,name=" + executors[i].getName());                    Registry.getRegistry(null, null)                        .registerComponent(executors[i], executorObjectName, null);                }                            } catch (Exception e) {                log.error(sm.getString("standardService.register.failed",domain),e);            }                                }        if( server==null ) {            // Register with the server             // HACK: ServerFactory should be removed...                        ServerFactory.getServer().addService(this);        }                       // Initialize our defined Connectors        synchronized (connectors) {                for (int i = 0; i < connectors.length; i++) {                    connectors[i].initialize();                }        }    }

connector.java

 1     public void initialize() 2         throws LifecycleException 3     { 4         if (initialized) { 5             if(log.isInfoEnabled()) 6                 log.info(sm.getString("coyoteConnector.alreadyInitialized")); 7            return; 8         } 9 10         this.initialized = true;11 12         if( oname == null && (container instanceof StandardEngine)) {13             try {14                 // we are loaded directly, via API - and no name was given to us15                 StandardEngine cb=(StandardEngine)container;16                 oname = createObjectName(cb.getName(), "Connector");17                 Registry.getRegistry(null, null)18                     .registerComponent(this, oname, null);19                 controller=oname;20             } catch (Exception e) {21                 log.error( "Error registering connector ", e);22             }23             if(log.isDebugEnabled())24                 log.debug("Creating name for connector " + oname);25         }26 27         // Initializa adapter28         adapter = new CoyoteAdapter(this);29         protocolHandler.setAdapter(adapter);30 31         IntrospectionUtils.setProperty(protocolHandler, "jkHome",32                                        System.getProperty("catalina.base"));33 34         try {35             protocolHandler.init();36         } catch (Exception e) {37             throw new LifecycleException38                 (sm.getString39                  ("coyoteConnector.protocolHandlerInitializationFailed", e));40         }41     }

Http11Protocol.java初始化

 1     public void init() throws Exception { 2         endpoint.setName(getName()); 3         endpoint.setHandler(cHandler); 4  5         // Verify the validity of the configured socket factory 6         try { 7             if (isSSLEnabled()) { 8                 sslImplementation = 9                     SSLImplementation.getInstance(sslImplementationName);10                 socketFactory = sslImplementation.getServerSocketFactory();11                 endpoint.setServerSocketFactory(socketFactory);12             } else if (socketFactoryName != null) {13                 socketFactory = (ServerSocketFactory) Class.forName(socketFactoryName).newInstance();14                 endpoint.setServerSocketFactory(socketFactory);15             }16         } catch (Exception ex) {17             log.error(sm.getString("http11protocol.socketfactory.initerror"),18                       ex);19             throw ex;20         }21 22         if (socketFactory!=null) {23             Iterator<String> attE = attributes.keySet().iterator();24             while( attE.hasNext() ) {25                 String key = attE.next();26                 Object v=attributes.get(key);27                 socketFactory.setAttribute(key, v);28             }29         }30         31         try {32             endpoint.init();33         } catch (Exception ex) {34             log.error(sm.getString("http11protocol.endpoint.initerror"), ex);35             throw ex;36         }37         if (log.isInfoEnabled())38             log.info(sm.getString("http11protocol.init", getName()));39 40     }

 JIoEndpoint.java

 * Handle incoming TCP connections.
 *
 * This class implement a simple server model: one listener thread accepts on a socket and
 * creates a new worker thread for each incoming connection.
 *
 * More advanced Endpoints will reuse the threads, use queues, etc.

 1     public void init() 2         throws Exception { 3  4         if (initialized) 5             return; 6          7         // Initialize thread count defaults for acceptor 8         if (acceptorThreadCount == 0) { 9             acceptorThreadCount = 1;10         }11         if (serverSocketFactory == null) {12             serverSocketFactory = ServerSocketFactory.getDefault();13         }14         if (serverSocket == null) {15             try {16                 if (address == null) {17                     serverSocket = serverSocketFactory.createSocket(port, backlog);18                 } else {19                     serverSocket = serverSocketFactory.createSocket(port, backlog, address);20                 }21             } catch (BindException be) {22                 if (address == null)23                     throw new BindException(be.getMessage() + "<null>:" + port);24                 else25                     throw new BindException(be.getMessage() + " " +26                             address.toString() + ":" + port);27             }28         }29         //if( serverTimeout >= 0 )30         //    serverSocket.setSoTimeout( serverTimeout );31         32         initialized = true;33         34     }

 

b1) initDirs() -> set properties like                   catalina.home                  catalina.base == catalina.home (most cases)b2) initNamingsetProperty(javax.naming.Context.INITIAL_CONTEXT_FACTORY,    org.apache.naming.java.javaURLContextFactory ->default)b3) createStartDigester() Configures a digester for the main server.xml elements likeorg.apache.catalina.core.StandardServer (can change of course :)org.apache.catalina.deploy.NamingResourcesStores naming resources in the J2EE JNDI treeorg.apache.catalina.LifecycleListenerimplements events for start/stop of major componentsorg.apache.catalina.core.StandardServiceThe single entry for a set of connectors,so that a container can listen to multiple connectorsie, single entryorg.apache.coyote.tomcat5.CoyoteConnectorConnectors to listen for incoming requests onlyIt also adds the following rulesets to the digesterNamingRuleSetEngineRuleSetHostRuleSetContextRuleSetb4) Load the server.xml and parse it using the digester    Parsing the server.xml using the digester is an automatic    XML-object mapping tool, that will create the objects defined in server.xml    Startup of the actual container has not started yet.b5) Assigns System.out and System.err to the SystemLogHandler classb6) Calls initialize on all components, this makes each object register itself with the     JMX agent.    During the process call the Connectors also initialize the adapters.    The adapters are the components that do the request pre-processing.    Typical adapters are HTTP1.1 (default if no protocol is specified,    org.apache.coyote.http11.Http11Protocol)    AJP1.3 for mod_jk etc.

 

 

 

原创粉丝点击