tomcat解析(十)StandardService.initialize.start
2010-02-02 18:04
323 查看
先上代码:
一.initialize
主要的内容有三部分:
1.Registry.getRegistry(null, null).registerComponent(executors[i], executorObjectName, null);
使用MBean注册组件
2.ServerFactory.getServer().addService(this);
ServerFactory.getServer()返回的对象为StandardServer对象,而在实例化StandardService时已经调用了该方法进行设置了,因此这里其它是做多了一次设置
3.connectors[i].initialize();
分别调用所有connectors的initialize()方法,该方法如下:
可看到实例化了adapter对象后,最终调用了protocolHandler.init(),其中protocolHandler对象实例化过程如下:
因此这里将调用的是Http11Protocol的方法 ,我们再看Http11Protocol.init到底做了什么事
前一部分是在设置endpoint对象的属性,最后调用其Init方法,如下:
最终产生了一个ServerSocket对象,虽然有ServerSocket,但还需要执行其accept()才能获取客户端请求的,因此这里其实还不能处理请求.
二.start
主要的内容有二部分:
1.lifecycle.fireLifecycleEvent
触发Lifecycle事件,这里没有注册相应的监听器
2.((Lifecycle) container).start();executors.get(i).start();((Lifecycle) connectors[i]).start();
调用了几元素的start方法
这里的container,executors及connectors从何而来呢?
1.executors是需要在server.xml里配置Server/Service/Executor的,如果进行了配置,将产生类型为org.apache.catalina.core.StandardThreadExecutor的对象,并全部放入StandardService的ArrayList<Executor> executors里
2.connectors与executors一样,也要进行配置,路径为Server/Service/Connector,对象类型为:org.apache.catalina.connector.Connector
3.container则需要查看Catalina.createStartDigester里的内容,有一句代码如下:
digester.addRuleSet(new EngineRuleSet("Server/Service/"));
查看EngineRuleSet对象addRuleInstances方法,可看到将添加ObjectCreateRule创建类型为org.apache.catalina.core.StandardEngine的对象,并调用StandardService.setContainer,对象将放入StandardService的container变量里,同时放入Connector的container变量,而该StandardService对象将放入StandardEngine的service变量里,因此这里将调用StandardEngine.start();
这里需要注意的是container.start的调用是在Connector之前的,这样做是有理由的;container.start()里将会为服务器准备所有工程项目的解析及部署工作,而Connector.start()将会让tomcat开始接受并处理用户的请求,因此是需要放在工程部署准备完成之后的,因此Connector.start()我们将放在最后来讲,下一篇目我们讲的是StandardEngine
一.initialize
/** * Invoke a pre-startup initialization. This is used to allow connectors * to bind to restricted ports under Unix operating environments. */ 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(); } } }
主要的内容有三部分:
1.Registry.getRegistry(null, null).registerComponent(executors[i], executorObjectName, null);
使用MBean注册组件
2.ServerFactory.getServer().addService(this);
ServerFactory.getServer()返回的对象为StandardServer对象,而在实例化StandardService时已经调用了该方法进行设置了,因此这里其它是做多了一次设置
3.connectors[i].initialize();
分别调用所有connectors的initialize()方法,该方法如下:
/** * Initialize this connector (create ServerSocket here!) */ public void initialize() throws LifecycleException { if (initialized) { if(log.isInfoEnabled()) log.info(sm.getString("coyoteConnector.alreadyInitialized")); return; } this.initialized = true; if( oname == null && (container instanceof StandardEngine)) { try { // we are loaded directly, via API - and no name was given to us StandardEngine cb=(StandardEngine)container; oname = createObjectName(cb.getName(), "Connector"); Registry.getRegistry(null, null) .registerComponent(this, oname, null); controller=oname; } catch (Exception e) { log.error( "Error registering connector ", e); } if(log.isDebugEnabled()) log.debug("Creating name for connector " + oname); } // Initializa adapter adapter = new CoyoteAdapter(this); protocolHandler.setAdapter(adapter); IntrospectionUtils.setProperty(protocolHandler, "jkHome", System.getProperty("catalina.base")); try { protocolHandler.init(); } catch (Exception e) { throw new LifecycleException (sm.getString ("coyoteConnector.protocolHandlerInitializationFailed", e)); } }
可看到实例化了adapter对象后,最终调用了protocolHandler.init(),其中protocolHandler对象实例化过程如下:
/** * Coyote Protocol handler class name. * Defaults to the Coyote HTTP/1.1 protocolHandler. */ protected String protocolHandlerClassName = "org.apache.coyote.http11.Http11Protocol"; ...... public Connector(String protocol) throws Exception { setProtocol(protocol); // Instantiate protocol handler try { Class clazz = Class.forName(protocolHandlerClassName); this.protocolHandler = (ProtocolHandler) clazz.newInstance(); } catch (Exception e) { log.error (sm.getString ("coyoteConnector.protocolHandlerInstantiationFailed", e)); } }
因此这里将调用的是Http11Protocol的方法 ,我们再看Http11Protocol.init到底做了什么事
protected Http11ConnectionHandler cHandler = new Http11ConnectionHandler(this); protected JIoEndpoint endpoint = new JIoEndpoint(); ...... public void init() throws Exception { endpoint.setName(getName()); endpoint.setHandler(cHandler); // Verify the validity of the configured socket factory try { if (isSSLEnabled()) { sslImplementation = SSLImplementation.getInstance(sslImplementationName); socketFactory = sslImplementation.getServerSocketFactory(); endpoint.setServerSocketFactory(socketFactory); } else if (socketFactoryName != null) { socketFactory = (ServerSocketFactory) Class.forName(socketFactoryName).newInstance(); endpoint.setServerSocketFactory(socketFactory); } } catch (Exception ex) { log.error(sm.getString("http11protocol.socketfactory.initerror"), ex); throw ex; } if (socketFactory!=null) { Iterator<String> attE = attributes.keySet().iterator(); while( attE.hasNext() ) { String key = attE.next(); Object v=attributes.get(key); socketFactory.setAttribute(key, v); } } try { endpoint.init(); } catch (Exception ex) { log.error(sm.getString("http11protocol.endpoint.initerror"), ex); throw ex; } if (log.isInfoEnabled()) log.info(sm.getString("http11protocol.init", getName())); }
前一部分是在设置endpoint对象的属性,最后调用其Init方法,如下:
public void init() throws Exception { if (initialized) return; // Initialize thread count defaults for acceptor if (acceptorThreadCount == 0) { acceptorThreadCount = 1; } if (serverSocketFactory == null) { serverSocketFactory = ServerSocketFactory.getDefault(); } if (serverSocket == null) { try { if (address == null) { serverSocket = serverSocketFactory.createSocket(port, backlog); } else { serverSocket = serverSocketFactory.createSocket(port, backlog, address); } } catch (BindException be) { if (address == null) throw new BindException(be.getMessage() + "<null>:" + port); else throw new BindException(be.getMessage() + " " + address.toString() + ":" + port); } } //if( serverTimeout >= 0 ) // serverSocket.setSoTimeout( serverTimeout ); initialized = true; }
最终产生了一个ServerSocket对象,虽然有ServerSocket,但还需要执行其accept()才能获取客户端请求的,因此这里其实还不能处理请求.
二.start
/** * Prepare for the beginning of active use of the public methods of this * component. This method should be called before any of the public * methods of this component are utilized. It should also send a * LifecycleEvent of type START_EVENT to any registered listeners. * * @exception LifecycleException if this component detects a fatal error * that prevents this component from being used */ public void start() throws LifecycleException { // Validate and update our current component state if (log.isInfoEnabled() && started) { log.info(sm.getString("standardService.start.started")); } if( ! initialized ) init(); // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null); if(log.isInfoEnabled()) log.info(sm.getString("standardService.start.name", this.name)); lifecycle.fireLifecycleEvent(START_EVENT, null); started = true; // Start our defined Container first if (container != null) { synchronized (container) { if (container instanceof Lifecycle) { ((Lifecycle) container).start(); } } } synchronized (executors) { for ( int i=0; i<executors.size(); i++ ) { executors.get(i).start(); } } // Start our defined Connectors second synchronized (connectors) { for (int i = 0; i < connectors.length; i++) { if (connectors[i] instanceof Lifecycle) ((Lifecycle) connectors[i]).start(); } } // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null); }
主要的内容有二部分:
1.lifecycle.fireLifecycleEvent
触发Lifecycle事件,这里没有注册相应的监听器
2.((Lifecycle) container).start();executors.get(i).start();((Lifecycle) connectors[i]).start();
调用了几元素的start方法
这里的container,executors及connectors从何而来呢?
1.executors是需要在server.xml里配置Server/Service/Executor的,如果进行了配置,将产生类型为org.apache.catalina.core.StandardThreadExecutor的对象,并全部放入StandardService的ArrayList<Executor> executors里
2.connectors与executors一样,也要进行配置,路径为Server/Service/Connector,对象类型为:org.apache.catalina.connector.Connector
3.container则需要查看Catalina.createStartDigester里的内容,有一句代码如下:
digester.addRuleSet(new EngineRuleSet("Server/Service/"));
查看EngineRuleSet对象addRuleInstances方法,可看到将添加ObjectCreateRule创建类型为org.apache.catalina.core.StandardEngine的对象,并调用StandardService.setContainer,对象将放入StandardService的container变量里,同时放入Connector的container变量,而该StandardService对象将放入StandardEngine的service变量里,因此这里将调用StandardEngine.start();
这里需要注意的是container.start的调用是在Connector之前的,这样做是有理由的;container.start()里将会为服务器准备所有工程项目的解析及部署工作,而Connector.start()将会让tomcat开始接受并处理用户的请求,因此是需要放在工程部署准备完成之后的,因此Connector.start()我们将放在最后来讲,下一篇目我们讲的是StandardEngine
相关文章推荐
- tomcat解析(九)StandardServer.initialize.start
- tomcat解析(十五)StandardContext.start的其它内容
- tomcat(supplement)HttpConnector.initialize() 和 start() 方法 以及 StandardContext.start()方法的分析
- tomcat解析(十一)StandardEngine.start
- error:org.apache.catalina.LifecycleException:Failed to start component[StandardService[Tomcat]]
- 知识库--StandardService + Lifecycle(start/stop)+initialize(72)
- Service#onStartCommand返回值解析
- tomcat的service.bat注册成服务不能调用系统证书,而手动启动start.bat却可以
- tomcat 启动异常 Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardCont
- tomcat部署项目时出错(Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardC)
- Tomcat启动报错 Failed to start component [StandardServer[8005]]解决
- myeclipse中启动tomcat的问题 (Source not found for StandardContext.start())
- Failed to start component [StandardEngine[Tomcat].StandardHost[localhost].StandardContext
- 将tomcat服务注册到service中,使用service tomcat start启动
- tomcat运行时出现了Failed to start component [StandardEngine[Catalina].StandardHost[localhost]]等错误
- Tomcat启动报错 Failed to start component [StandardServer[8005]]解决
- Eclipse中部署项目时,Tomcat启动报错 “Failed to start component [StandardServer[8005]]”的解决
- spring boot 1.4 打成jar包启动失败,报Failed to start component [StandardEngine[Tomcat].StandardHost[localhost
- tomcat解析(三)bootstrap.load.start
- org.apache.catalina.LifecycleException: Failed to start component [StandardService[Catalina]]