前言
之前我写的Tomcat,都是通过获取socket对象,然后通过socket对象的输入输出流完成的.引入Netty之后,由于需要通过ByteBuf进行相关的操作,本次有较大的改动,将core包中的核心类都进行了更改.
GitHub地址:https://github.com/shenshaoming/tomcat
代码
首先是主程序HttpServer,更改为Netty后代码有所减少:
package com.tomcat.core;
import com.tomcat.annotations.Servlet;
import com.tomcat.baseservlet.AbstractServlet;
import com.tomcat.exceptions.RequestMappingException;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.ServerSocketChannel;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import java.io.File;
import java.io.IOException;
import java.net.*;
import java.util.*;
import java.util.concurrent.*;
/**
* Netty版本的tomcat
* 监听请求,调用request和response对请求作出反应
* @author 申劭明
* @date 2019/9/16 17:21
* @version 5.3
*/
public class HttpServer {
/**
* 线程池中核心线程数的最大值(不是操作系统的最大值)
*/
private int corePoolSize = 10;
/**
* 最大队列空间
*/
private int maximumPoolSize = 50;
/**
* 空闲线程的最大存活时间
*/
private long keepAliveTime = 100L;
/**
* keepAliveTime的时间单位设置
*/
private TimeUnit unit = TimeUnit.SECONDS;
/**
* 监听端口
*/
private static int port = 8080;
/**
* 关闭服务器的请求URI
*/
static final String CLOSE_URI = "/shutdown";
/**
* Key值为Servlet的别名(uri),value为该Servlet对象
* default权限
*/
static HashMap<String, AbstractServlet> map;
static {
//包名,可以通过application.properties设置
getServlets("com.tomcat.servlet");
}
/**
* @Description : nio监听数据请求
* @author : 申劭明
* @date : 2019/9/17 10:29
*/
public void acceptWait() {
//监听请求
EventLoopGroup listenGroup = new NioEventLoopGroup();
//请求处理
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap();
//绑定监听请求和处理请求的group
bootstrap.group(listenGroup,workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(new RequestHandler());
}
});
ChannelFuture future = null;
try {
future = bootstrap.bind(port).sync();
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
listenGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
/**
* @param packageName 包名,如com.tomcat.servlet
* @return : void
* @Description : 扫描packageName包下的所有带有@Servlet注解的类文件
*