假设来自客户的请求为:
http://localhost:8080/wsota/wsota_index.jsp

1) 请求被发送到本机端口8080,被在那里侦听的Coyote HTTP/1.1 Connector获得
2) Connector把该请求交给它所在的Service的Engine来处理,并等待来自Engine的回应
3) Engine获得请求localhost/wsota/wsota_index.jsp,匹配它所拥有的所有虚拟主机Host
4) Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机)
5) localhost Host获得请求/wsota/wsota_index.jsp,匹配它所拥有的所有Context
6) Host匹配到路径为/wsota的Context(如果匹配不到就把该请求交给路径名为""的Context去处理)
7) path="/wsota"的Context获得请求/wsota_index.jsp,在它的mapping table中寻找对应的servlet
8) Context匹配到URL PATTERN为*.jsp的servlet,对应于JspServlet类
9) 构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet或doPost方法
10)Context把执行完了之后的HttpServletResponse对象返回给Host
11)Host把HttpServletResponse对象返回给Engine
12)Engine把HttpServletResponse对象返回给Connector
13)Connector把HttpServletResponse对象返回给客户browser

posted @ 2011-05-13 11:44 xsong 阅读(164) | 评论 (0)编辑 收藏

Bootstrap 的 init 方法中 通过反射动态调用 Catalina.start() 
Catalina 类 负责开始或者停止服务
 Class<?> startupClass = catalinaLoader.loadClass("org.apache.catalina.startup.Catalina");
 Object startupInstance 
= startupClass.newInstance();
Catalina 完成了3个任务 
  •  处理xml文件, load 方法中使用 Digester 处理server.xml文件,转化为java对象
if (getServer() == null) {
            load();
        }
  •     实例化一个server  

 getServer().start();
  •      给jvm 注册一个关闭 的Hook(钩子)
Runtime.getRuntime().addShutdownHook(shutdownHook);
  • 线程等待
 await();  调用 StandardServer 的 await()   StandardServer 处理 Server相关的操作,
     /**
     * Wait until a proper shutdown command is received, then return.
     * This keeps the main thread alive - the thread pool listening for http
     * connections is daemon threads.
     */
     StandardServer.await() 处理 当前的主线程,即 启动 tomcat 的主线程

    
try {
        awaitSocket 
= new ServerSocket(port, 1,
                InetAddress.getByName(address));
    }

    
catch( IOException e ) {
        log.error(
"StandardServer.await: create[" + address + ":" + port + "]: ", e);
        
return;
    }

    
try {
        awaitThread 
= Thread.currentThread();

// Loop waiting for a connection and a valid command
        while (!stopAwait) {
            ServerSocket serverSocket 
= awaitSocket;

            
if (serverSocket == null) {
                
break;
            }
// Wait for the next connection
            Socket socket = null;
            StringBuilder command 
= new StringBuilder();
            
try {
                InputStream stream;
                
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) {
                    
if (stopAwait) {
// Wait was aborted with socket.close()
                        break;
                    }
                    log.error(
"StandardServer.await: accept: ", e);
                    
break;
                }
// Read a set of characters from the socket
                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(
"StandardServer.await: read: ", e);
                        ch 
= -1;
                    }
                    
if (ch < 32)  // Control character or EOF terminates loop
                        break;
                    command.append((
char) ch);
                    expected
--;
                }
            } 
finally {
// Close the socket now that we are done with it
                try {
                    
if (socket != null) {
                        socket.close();
                    }
                } 
catch (IOException e) {
// Ignore
                }
            }

// Match against our command string
            boolean match = command.toString().equals(shutdown);
            
if (match) {
                log.info(sm.getString(
"standardServer.shutdownViaPort"));
                
break;
            } 
else
                log.warn(
"StandardServer.await: Invalid command '"
                        
+ command.toString() + "' received");
        }
    }

    
finally {
        ServerSocket serverSocket 
= awaitSocket;
        awaitThread 
= null;
        awaitSocket 
= null;
// Close the server socket and return
        if (serverSocket != null) {
            
try {
                serverSocket.close();
            } 
catch (IOException e) {
// Ignore
            }
        }
    }

posted @ 2011-05-13 11:31 xsong 阅读(531) | 评论 (0)编辑 收藏

 

class A {
  
void call() {}  
}
  
class B extends A {
  
void call() {}  
}
  
class C {
  
void call() {}  
}
 
void foo(A a){
}

A a
=new A();
foo(a); 

C c
=new C();
foo(c);
java编译器无法通过, 因为C不是A或者A的子类 虽然 C 中也有 call 方法。

scala 中可以通过 结构类型(Structural)实现
class A {
  def call() 
{
    println(
"a class")
  }

}

class B extends A {override def call() {}}
class C {
  def call() 
{
    println(
"c class")
  }

}


object Call 
{
  def main(args: Array[String]) 
{
    def foo[T 
<{ def call() }](a : T) {
      a.call()
    }

    val a 
= new A()
    val c 
= new C()
    foo(a)
    foo(c)
    println()
  }

}

不过觉得  def foo[T <: { def call() }](a : T)  这样的写法 不如动态语言(ruby, groovy..)看起来自然。

posted @ 2010-01-12 18:02 xsong 阅读(135) | 评论 (0)编辑 收藏

    java中的泛型:
List<String> s1=new ArrayList<String>();
        s1.add(
"hello");
当在s1中添加 String 类型以外的对象时,编译器会报错。
s1.add(new Date());
scala 中是用 [] 代替 java 中的<> 表达泛型。scala 在new ArrayList时,不需要指定String类型,得益与scala 的类型推断。
val strs : List[String]=new ArrayList()
scala 中定义泛型列表,和java中类似
class Link[T](val head: T, val tail: Link[T]) 
协变的定义:    假设有类G(或者接口和特征) 和类型T1,T2  。 在T1是T2的子类的情况下, 如果G<T1> 也是G2<T2>的子类,则类G是协变的。

当我定义一个列表对象li,并定义一个ln为li 的别名
 List<Integer> li=new ArrayList<Integer>();
        li.add(
1);
        List
<Number> ln=li;

这样的方式,编译器不能通过。
通过协变,可以实现上诉功能
class Link[+T](val head : T, val tail: Link[T]) {}

def main(args : Array[String])
{
      val ln : Link[Integer]
=new Link[Integer](1,null)
      val lnn : Link[Number]
=ln
      println(lnn.head)
}


但是如果试图加入一个方法,追加一个参数,并返回Link, 则会产生编译错误
class Link[+T](val head : T, val tail: Link[T]) {

 def prepend(newHead: T): Link[T] 
= new Link(newHead, this)
}

 
实际上,范型变为协变之后就不能把类型参数不加修改的放在成员方法的参数上(这里是newHead)了。但是,通过将成员方法定义为范型,并按照如下所示描述后就可以避免该问题了

class Link[+T](val head: T, val tail: Link[T]) {  
    def prepend[U 
>: T](newHead: U): Link[U] = new Link(newHead, this)  
}
 
scala 逆变,类似协变
假设有类 G 和类型T1,T2, 在T1 是T2的子类的情况,如果G[T2]是G[T1]的子类, 则G为逆变。
假设含有 apply的类 LessThan(apply 的逻辑 当a<b 时,返回true 否则返回false)
abstract class LessThan[T] {
  def apply(a: T, b: T): Boolean
}
val hashCodeLt: LessThan[Any] = new LessThan[Any] {
      def apply(a: Any, b: Any): Boolean 
= a.hashCode < b.hashCode
    }


    val strLt: LessThan[String] 
= hashCodeLt

    
assert(true ,strLt("a","b"))
在非变的情况 编译器会报错:Error:Error:line (18)error: type mismatch;
found   : xxx.LessThan[Any]
required: xxx.LessThan[String]
val strLt: LessThan[String] = hashCodeLt
在需要LessThan[Any]的地方使用了LessThan[String],由此看来LessThan不是逆变的,也不是协变,可以成为非变。
但是在类的定义前加一个 - 符号,使用逆变, 代码则可编译过去了。
abstract class LessThan[-T] {
  def apply(a: T, b: T): Boolean
}



posted @ 2010-01-12 17:20 xsong 阅读(706) | 评论 (0)编辑 收藏

java 有很庞大的类库资源,但是 被声明成 final 的类不允许继承 例如 String , 怎样扩展java及第三方类库 scala提供了很灵活的方式

当 scala 使用 implicit 隐式转化时 ,  scala 编辑器发现对象的类型不匹配时,不会直接报错,而会在代码中尝试匹配implicit声明的object, 当然,相同方法签名的类必须唯一。
举个小例子,实现在字符串前后 添加 "**" 的操作。

当然 例子本事无实际意义, 只是说明implicit的用法而已 
 1object implicits {
 2
 3  implicit  def strWrapper(s : String)={
 4    new {
 5      def wrap= "**"+s+"**"
 6    }

 7  }

 8  def main(args: Array[String]) {
 9    val s = "hello"
10    println(s.wrap)  // **hello**
11  }

12}

当scala的编译器 编译 s.wrap 时,因为 String 类中没有 wrap方法,编译器会寻找代码中方法签名相同的 strWrapper(s :String),
输出  **hello**

另外一种写法 :

 1object implicits {
 2
 3  class StrWrapper(s : String){
 4    def wrap="**"+s+"**"
 5  }

 6  def main(args: Array[String]) {
 7    implicit def wrapper(s :String)=new StrWrapper(s)
 8    val s = "hello" 
 9    println(s.wrap) // print **hello**
10  }

11}

posted @ 2009-12-23 17:17 xsong 阅读(4143) | 评论 (0)编辑 收藏

仅列出标题
共3页: 上一页 1 2 3