设为首页 收藏本站
查看: 1321|回复: 0

[经验分享] tomcat源码阅读_代码篇4

[复制链接]

尚未签到

发表于 2015-8-10 08:05:21 | 显示全部楼层 |阅读模式
  StandardServer类:
  该类的签名如下:
  public final class StandardServer      implements Lifecycle, Server, MBeanRegistration
  该类实现了Lifecycle, Server, MBeanRegistration接口。
  Lifecycle接口是Catalina的组件的通用声明周期方法的接口,组件可以选择实现该接口。该接口定义了声明周期统一启动停止机制。方法定义如下:
  
[size=-1]voidaddLifecycleListener(LifecycleListener listener)
            Add a LifecycleEvent listener to this component.
[size=-1]LifecycleListener[] findLifecycleListeners()
            Get the lifecycle listeners associated with this lifecycle.
[size=-1]voidremoveLifecycleListener(LifecycleListener listener)
            Remove a LifecycleEvent listener from this component.
[size=-1]voidstart()
            Prepare for the beginning of active use of the public methods of this component.
[size=-1]voidstop()
            Gracefully terminate the active use of the public methods of this component.

  另外,还是用静态变量定义了一些常量:
  如:   
  /**
      * The LifecycleEvent type for the "component init" event.
      */
     public static final String INIT_EVENT = "init";
  Server接口表示整个Catalina servlet容器,它的属性代表了整个servlet容器的属性,一个Server可以有多个service,以及顶层命名资源集。
  该接口的实现要在指定端口上建立一个Server socket,是用其来监测连接,收到连接后首先需要跟关闭指令进行比较,如果是关闭指令则关闭服务。否则继续服务。
  MBeanRegistration 接口:
  该接口表示可以由 MBean 实现,以便在向 MBean 服务器注册或从其注销之前和之后执行操作。
  
[size=-1]voidpostDeregister()
            允许 MBean 在已从 MBean 服务器注销之后执行所需要的任何操作。
[size=-1]voidpostRegister(Boolean registrationDone)
            允许 MBean 在被注册到 MBean 服务器或注销失败后执行任何所需要的操作。
[size=-1]voidpreDeregister()
            允许该 MBean 在从 MBean 服务器注销之前执行它所需要的任何操作。
[size=-1]ObjectNamepreRegister(MBeanServer server, ObjectName name)
            允许 MBean 在被注册到 MBean 服务器之前执行它所需要的任何操作。

  构造函数如下:
  public StandardServer() {
  super();
         ServerFactory.setServer(this);//设置ServerFactory里的Server对象
  globalNamingResources = new NamingResources();//命名资源,这个类后面再看~~
         globalNamingResources.setContainer(this);//设置命名资源的容器
  if (isUseNaming()) {
             if (namingContextListener == null) {
                 namingContextListener = new NamingContextListener();
                 addLifecycleListener(namingContextListener);
             }
         }
  }
  addService方法   
  public void addService(Service service) {
  service.setServer(this);
  synchronized (services) {
             Service results[] = new Service[services.length + 1];
             System.arraycopy(services, 0, results, 0, services.length);
             results[services.length] = service;
             services = results;
  if (initialized) {
                 try {
                     service.initialize();
                 } catch (LifecycleException e) {
                     log.error(e);
                 }
             }
  if (started && (service instanceof Lifecycle)) {
                 try {
                     ((Lifecycle) service).start();
                 } catch (LifecycleException e) {
                     ;
                 }
             }
  // Report this property change to interested listeners
             support.firePropertyChange("service", null, service);
         }
  }
  这个方法的实现个人认为不太好,我尝试将其改为如下内容:
  ListservList=Arrays.asList(services);
         servList.add(service);
         services=servList.toArray(new Service[0]);
  修改1:等整个修改完后会测试下修改后的性能
  
  await方法:
  public void await() {
         // Negative values - don't wait on port - tomcat is embedded or we just don't like ports
         if( port == -2 ) {
             // undocumented yet - for embedding apps that are around, alive.
             return;
         }
         if( port==-1 ) {
             while( true ) {
                 try {
                     Thread.sleep( 10000 );
                 } catch( InterruptedException ex ) {
                 }
                 if( stopAwait ) return;
             }
         }
         
         // Set up a server socket to wait on
         ServerSocket serverSocket = null;
         try {
             serverSocket =
                 new ServerSocket(port, 1,
                                  InetAddress.getByName("localhost"));
         } catch (IOException e) {
             log.error("StandardServer.await: create[" + port
                                + "]: ", e);
             System.exit(1);
         }
  // Loop waiting for a connection and a valid command
         while (true) {
  // Wait for the next connection
             Socket socket = null;
             InputStream stream = null;
             try {
                 socket = serverSocket.accept();
                 socket.setSoTimeout(10 * 1000); // Ten seconds
                 stream = socket.getInputStream();
             } catch (AccessControlException ace) {
                 log.warn("StandardServer.accept security exception: "
                                    + ace.getMessage(), ace);
                 continue;
             } catch (IOException e) {
                 log.error("StandardServer.await: accept: ", e);
                 System.exit(1);
             }
  // Read a set of characters from the socket
             StringBuffer command = new StringBuffer();
             int expected = 1024; // Cut off to avoid DoS attack
             while (expected < shutdown.length()) {
                 if (random == null)
                     random = new Random();
                 expected += (random.nextInt() % 1024);
             }
             while (expected > 0) {
                 int ch = -1;
                 try {
                     ch = stream.read();
                 } catch (IOException e) {
                     log.warn(&quot;StandardServer.await: read: &quot;, e);
                     ch = -1;
                 }
                 if (ch < 32) // Control character or EOF terminates loop
                     break;
                 command.append((char) ch);
                 expected--;
             }
  // Close the socket now that we are done with it
             try {
                 socket.close();
             } catch (IOException e) {
                 ;
             }
  // Match against our command string
             boolean match = command.toString().equals(shutdown);
             if (match) {
                 break;
             } else
                 log.warn(&quot;StandardServer.await: Invalid command '&quot; +
                                    command.toString() + &quot;' received&quot;);
  }
  // Close the server socket and return
         try {
             serverSocket.close();
         } catch (IOException e) {
             ;
         }
  }
这段代码会创建一个ServerSocket,绑定到8005端口上,然后进入一个循环,在循环中会一直接受连接,直到收到关闭命令的时候,跳出循环,执行serverSocket.close()方法关闭服务器。
  public void removeService(Service service) {
  synchronized (services) {
             int j = -1;
             for (int i = 0; i < services.length; i++) {
                 if (service == services) {
                     j = i;
                     break;
                 }
             }
             if (j < 0)
                 return;
             if (services[j] instanceof Lifecycle) {
                 try {
                     ((Lifecycle) services[j]).stop();
                 } catch (LifecycleException e) {
                     ;
                 }
             }
             int k = 0;
             Service results[] = new Service[services.length - 1];
             for (int i = 0; i < services.length; i++) {
                 if (i != j)
                     results[k++] = services;
             }
             services = results;
  // Report this property change to interested listeners
             support.firePropertyChange(&quot;service&quot;, service, null);
         }
  }
  这段代码实现的还是不错的~~~~...第二天我改变主意了,这段代码太复杂,可以简化下,我在standardService中进行修改,这里暂且不改了
  stop方法:
  public void stop() throws LifecycleException {
  // Validate and update our current component state
         if (!started)
             return;
  // Notify our interested LifecycleListeners
         lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null);
  lifecycle.fireLifecycleEvent(STOP_EVENT, null);
         started = false;
  // Stop our defined Services
         for (int i = 0; i < services.length; i++) {
             if (services instanceof Lifecycle)
                 ((Lifecycle) services).stop();
         }
  // Notify our interested LifecycleListeners
         lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);
  if (port == -1)
             stopAwait();
  }
  private LifecycleSupport lifecycle = new LifecycleSupport(this);
  这是负责生命周期的属性~~
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-96705-1-1.html 上篇帖子: tomcat配合实现basic与FORM验证 下篇帖子: 图解eclipse+tomcat配置jsp开发调试环境
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表