為什麼要把這兩個看起來不是很搭的東西放在一起對比呢?首先它們兩個都是網路程式設計框架和規範,而且通過我的觀察,從API的設計、生命週期方法、處理流程等等方面,他們確實有太多相似的地方了,如果想要深入地學習Netty,那麼對比著Servlet,一定能讓你事半功倍。
Servlet定義
首先,廣義上的Servlet是JavaEE的一種Web規範(類似aopalliance是面向切面程式設計的一種規範),其本身定義了web程式設計的基礎介面。遵循Servlet規範的應用程式可以執行在任何Servlet容器中,其實就是我們常見的Web伺服器如Tomcat、JBoss、Jetty等。同時Servlet規範也有一個同名的介面 -- Servlet介面,它定義了一個Servlet程式需要實現的方法。如下是javax.servlet-api-3.1.0.jar中定義的Servlet介面,可以看到有這三個生命週期方法:init、service、destroy,其中service
方法定義了用來處理網路請求的業務邏輯(注意,這裡不僅僅限於HTTP協議,也可以是FTP、STMP等)。
public interface Servlet {
// 如果重寫了init方法,一般要在第一行呼叫super.init(config)
public void init(ServletConfig config) throws ServletException;
public ServletConfig getServletConfig();
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;
public String getServletInfo();
public void destroy();
}
基於Servlet規範的應用程式其實可以響應所有型別的請求(不僅僅是HTTP,也可以是WebSocket、FTP等),但是在JavaEE中一般都是用來處理HTTP請求,所以Servlet介面有一個非常重要的實現類HttpServlet,我們熟知的Spring MVC框架中的派發器DispatcherServlet就是繼承自HttpServlet的。 其它更詳細的定義可以參考連結。
Netty定義
Netty是目前Java社群非常火熱的網路通訊框架,官網的定義是:Netty是一個基於非同步事件驅動的高效能的網路應用程式框架。跟Servlet規範有對應的同名Servlet介面稍有不同,Netty的介面定義更復雜,如果非要選出一個的話,我覺得是Channel,它定義了比Servlet更加廣泛的職能範圍,不僅定義了I/O操作,還定義了處理請求的業務邏輯。
public interface Channel extends AttributeMap, ChannelOutboundInvoker, Comparable<Channel> {
ChannelId id();
EventLoop eventLoop();
Channel parent();
ChannelConfig config();
boolean isOpen();
boolean isRegistered();
boolean isActive();
ChannelMetadata metadata();
SocketAddress localAddress();
SocketAddress remoteAddress();
ChannelFuture closeFuture();
boolean isWritable();
long bytesBeforeUnwritable();
long bytesBeforeWritable();
Unsafe unsafe();
ChannelPipeline pipeline();
ByteBufAllocator alloc();
@Override
Channel read();
@Override
Channel flush();
}
關於Netty更詳細的資料可參考連結。
Servlet和Netty都有生命週期方法,而Tomcat/JBoss/Jetty 與 Netty/Mina 就像是 Servlet 與 OIO/NIO 的關係。