第九章-Tomcat源码阅读与扩展

📚 第九章:Tomcat 源码阅读与扩展

目录

  • [9.1 启动入口分析](#9.1 启动入口分析)
  • [9.2 核心类分析](#9.2 核心类分析)
  • [9.3 Coyote 通信模块](#9.3 Coyote 通信模块)
  • [9.4 Container 生命周期与 Pipeline/Valve 机制](#9.4 Container 生命周期与 Pipeline/Valve 机制)
  • [9.5 自定义 Valve 实现](#9.5 自定义 Valve 实现)
  • [9.6 自定义 Filter 实现](#9.6 自定义 Filter 实现)
  • [9.7 源码调试技巧](#9.7 源码调试技巧)
  • [9.8 本章小结](#9.8 本章小结)

9.1 启动入口分析

9.1.1 Bootstrap 启动类

Bootstrap 类结构
java 复制代码
// Bootstrap 启动类
public final class Bootstrap {
    private static final String CATALINA_HOME_PROP = "catalina.home";
    private static final String CATALINA_BASE_PROP = "catalina.base";
    
    private Object catalinaDaemon = null;
    private ClassLoader commonLoader = null;
    private ClassLoader catalinaLoader = null;
    private ClassLoader sharedLoader = null;
    
    public static void main(String args[]) {
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.init();
        bootstrap.start();
    }
    
    public void init() throws Exception {
        // 1. 设置系统属性
        setCatalinaHome();
        setCatalinaBase();
        
        // 2. 创建类加载器
        initClassLoaders();
        
        // 3. 设置线程上下文类加载器
        Thread.currentThread().setContextClassLoader(catalinaLoader);
        
        // 4. 创建 Catalina 实例
        Class<?> startupClass = catalinaLoader.loadClass("org.apache.catalina.startup.Catalina");
        Object startupInstance = startupClass.getConstructor().newInstance();
        
        // 5. 设置 Catalina 属性
        String methodName = "setParentClassLoader";
        Class<?> paramTypes[] = new Class[1];
        paramTypes[0] = Class.forName("java.lang.ClassLoader");
        Object paramValues[] = new Object[1];
        paramValues[0] = sharedLoader;
        Method method = startupInstance.getClass().getMethod(methodName, paramTypes);
        method.invoke(startupInstance, paramValues);
        
        catalinaDaemon = startupInstance;
    }
    
    public void start() throws Exception {
        if (catalinaDaemon == null) {
            init();
        }
        
        Method method = catalinaDaemon.getClass().getMethod("start", (Class[]) null);
        method.invoke(catalinaDaemon, (Object[]) null);
    }
}
启动流程分析
java 复制代码
// 启动流程
public void init() throws Exception {
    // 1. 设置系统属性
    setCatalinaHome();
    setCatalinaBase();
    
    // 2. 创建类加载器
    initClassLoaders();
    
    // 3. 设置线程上下文类加载器
    Thread.currentThread().setContextClassLoader(catalinaLoader);
    
    // 4. 创建 Catalina 实例
    Class<?> startupClass = catalinaLoader.loadClass("org.apache.catalina.startup.Catalina");
    Object startupInstance = startupClass.getConstructor().newInstance();
    
    // 5. 设置 Catalina 属性
    String methodName = "setParentClassLoader";
    Class<?> paramTypes[] = new Class[1];
    paramTypes[0] = Class.forName("java.lang.ClassLoader");
    Object paramValues[] = new Object[1];
    paramValues[0] = sharedLoader;
    Method method = startupInstance.getClass().getMethod(methodName, paramTypes);
    method.invoke(startupInstance, paramValues);
    
    catalinaDaemon = startupInstance;
}

9.1.2 Catalina 启动类

Catalina 类结构
java 复制代码
// Catalina 启动类
public class Catalina {
    private Server server = null;
    private boolean await = false;
    private String configFile = "conf/server.xml";
    
    public void start() throws Exception {
        if (getServer() == null) {
            load();
        }
        
        if (getServer() == null) {
            log.fatal("Cannot start server. Server object is not configured.");
            return;
        }
        
        long t1 = System.nanoTime();
        
        // 启动服务器
        getServer().start();
        
        long t2 = System.nanoTime();
        if(log.isInfoEnabled()) {
            log.info("Server startup in " + ((t2 - t1) / 1000000) + " ms");
        }
        
        // 注册关闭钩子
        if (await) {
            await();
        }
    }
    
    public void load() throws Exception {
        // 1. 创建服务器
        if (getServer() == null) {
            loadFromArgs();
        }
        
        // 2. 启动服务器
        getServer().init();
    }
    
    public void stop() throws Exception {
        if (getServer() == null) {
            return;
        }
        
        getServer().stop();
    }
}
服务器创建过程
java 复制代码
// 服务器创建过程
public void loadFromArgs() throws Exception {
    // 1. 创建服务器
    Server server = new StandardServer();
    
    // 2. 设置服务器属性
    server.setPort(8005);
    server.setShutdown("SHUTDOWN");
    
    // 3. 创建服务
    Service service = new StandardService();
    service.setName("Catalina");
    
    // 4. 创建连接器
    Connector connector = new Connector("HTTP/1.1");
    connector.setPort(8080);
    service.addConnector(connector);
    
    // 5. 创建引擎
    Engine engine = new StandardEngine();
    engine.setName("Catalina");
    engine.setDefaultHost("localhost");
    
    // 6. 创建主机
    Host host = new StandardHost();
    host.setName("localhost");
    host.setAppBase("webapps");
    engine.addChild(host);
    
    // 7. 添加引擎到服务
    service.setContainer(engine);
    
    // 8. 添加服务到服务器
    server.addService(service);
    
    // 9. 设置服务器
    setServer(server);
}

9.2 核心类分析

9.2.1 StandardServer 分析

StandardServer 类结构
java 复制代码
// StandardServer 类
public class StandardServer extends LifecycleMBeanBase implements Server {
    private Service services[] = new Service[0];
    private int port = 8005;
    private String shutdown = "SHUTDOWN";
    private String address = "localhost";
    
    @Override
    protected void startInternal() throws LifecycleException {
        // 1. 设置状态
        setState(LifecycleState.STARTING);
        
        // 2. 启动服务
        for (Service service : services) {
            service.start();
        }
        
        // 3. 设置状态
        setState(LifecycleState.STARTED);
    }
    
    @Override
    protected void stopInternal() throws LifecycleException {
        // 1. 设置状态
        setState(LifecycleState.STOPPING);
        
        // 2. 停止服务
        for (Service service : services) {
            service.stop();
        }
        
        // 3. 设置状态
        setState(LifecycleState.STOPPED);
    }
    
    @Override
    public void addService(Service service) {
        service.setServer(this);
        Service results[] = new Service[services.length + 1];
        System.arraycopy(services, 0, results, 0, services.length);
        results[services.length] = service;
        services = results;
    }
}
服务管理
java 复制代码
// 服务管理
public class StandardServer extends LifecycleMBeanBase implements Server {
    private Service services[] = new Service[0];
    
    @Override
    public void addService(Service service) {
        service.setServer(this);
        Service results[] = new Service[services.length + 1];
        System.arraycopy(services, 0, results, 0, services.length);
        results[services.length] = service;
        services = results;
    }
    
    @Override
    public void removeService(Service service) {
        int j = -1;
        for (int i = 0; i < services.length; i++) {
            if (services[i] == service) {
                j = i;
                break;
            }
        }
        if (j >= 0) {
            Service results[] = new Service[services.length - 1];
            int n = 0;
            for (int i = 0; i < services.length; i++) {
                if (i != j) {
                    results[n++] = services[i];
                }
            }
            services = results;
        }
    }
}

9.2.2 StandardService 分析

StandardService 类结构
java 复制代码
// StandardService 类
public class StandardService extends LifecycleMBeanBase implements Service {
    private String name = null;
    private Server server = null;
    private Container container = null;
    private Connector connectors[] = new Connector[0];
    private Executor executor = null;
    
    @Override
    protected void startInternal() throws LifecycleException {
        // 1. 设置状态
        setState(LifecycleState.STARTING);
        
        // 2. 启动执行器
        if (executor != null) {
            executor.start();
        }
        
        // 3. 启动连接器
        for (Connector connector : connectors) {
            connector.start();
        }
        
        // 4. 启动容器
        if (container != null) {
            container.start();
        }
        
        // 5. 设置状态
        setState(LifecycleState.STARTED);
    }
    
    @Override
    protected void stopInternal() throws LifecycleException {
        // 1. 设置状态
        setState(LifecycleState.STOPPING);
        
        // 2. 停止容器
        if (container != null) {
            container.stop();
        }
        
        // 3. 停止连接器
        for (Connector connector : connectors) {
            connector.stop();
        }
        
        // 4. 停止执行器
        if (executor != null) {
            executor.stop();
        }
        
        // 5. 设置状态
        setState(LifecycleState.STOPPED);
    }
}
连接器管理
java 复制代码
// 连接器管理
public class StandardService extends LifecycleMBeanBase implements Service {
    private Connector connectors[] = new Connector[0];
    
    @Override
    public void addConnector(Connector connector) {
        connector.setService(this);
        Connector results[] = new Connector[connectors.length + 1];
        System.arraycopy(connectors, 0, results, 0, connectors.length);
        results[connectors.length] = connector;
        connectors = results;
    }
    
    @Override
    public void removeConnector(Connector connector) {
        int j = -1;
        for (int i = 0; i < connectors.length; i++) {
            if (connectors[i] == connector) {
                j = i;
                break;
            }
        }
        if (j >= 0) {
            Connector results[] = new Connector[connectors.length - 1];
            int n = 0;
            for (int i = 0; i < connectors.length; i++) {
                if (i != j) {
                    results[n++] = connectors[i];
                }
            }
            connectors = results;
        }
    }
}

9.2.3 StandardEngine 分析

StandardEngine 类结构
java 复制代码
// StandardEngine 类
public class StandardEngine extends ContainerBase implements Engine {
    private String defaultHost = null;
    private Service service = null;
    
    @Override
    protected void startInternal() throws LifecycleException {
        // 1. 设置状态
        setState(LifecycleState.STARTING);
        
        // 2. 启动子容器
        for (Container child : findChildren()) {
            child.start();
        }
        
        // 3. 设置状态
        setState(LifecycleState.STARTED);
    }
    
    @Override
    protected void stopInternal() throws LifecycleException {
        // 1. 设置状态
        setState(LifecycleState.STOPPING);
        
        // 2. 停止子容器
        for (Container child : findChildren()) {
            child.stop();
        }
        
        // 3. 设置状态
        setState(LifecycleState.STOPPED);
    }
    
    @Override
    public void invoke(Request request, Response response) throws IOException, ServletException {
        // 1. 获取主机名
        String hostname = request.getServerName();
        if (hostname == null) {
            hostname = getDefaultHost();
        }
        
        // 2. 查找主机
        Host host = findChild(hostname);
        if (host == null) {
            host = findChild(getDefaultHost());
        }
        
        // 3. 调用主机
        if (host != null) {
            host.invoke(request, response);
        } else {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST);
        }
    }
}

9.3 Coyote 通信模块

9.3.1 Http11NioProtocol 分析

Http11NioProtocol 类结构
java 复制代码
// Http11NioProtocol 类
public class Http11NioProtocol extends AbstractHttp11Protocol<NioChannel> {
    private NioEndpoint endpoint = null;
    
    @Override
    protected AbstractEndpoint.Handler<NioChannel> getHandler() {
        return new Http11ConnectionHandler(this);
    }
    
    @Override
    protected AbstractEndpoint<NioChannel> getEndpoint() {
        if (endpoint == null) {
            endpoint = new NioEndpoint();
            endpoint.setProtocol(this);
        }
        return endpoint;
    }
    
    @Override
    protected void configureEndpoint(AbstractEndpoint<NioChannel> endpoint) {
        super.configureEndpoint(endpoint);
        if (endpoint instanceof NioEndpoint) {
            NioEndpoint nioEndpoint = (NioEndpoint) endpoint;
            nioEndpoint.setSelectorTimeout(getSelectorTimeout());
            nioEndpoint.setPollerThreadCount(getPollerThreadCount());
            nioEndpoint.setPollerThreadPriority(getPollerThreadPriority());
        }
    }
}
连接处理器
java 复制代码
// 连接处理器
public class Http11ConnectionHandler extends AbstractConnectionHandler<NioChannel, Http11NioProcessor> {
    private final Http11NioProtocol protocol;
    
    public Http11ConnectionHandler(Http11NioProtocol protocol) {
        this.protocol = protocol;
    }
    
    @Override
    protected Http11NioProcessor createProcessor() {
        Http11NioProcessor processor = new Http11NioProcessor(this);
        processor.setAdapter(getAdapter());
        return processor;
    }
    
    @Override
    protected void processSocket(SocketWrapperBase<NioChannel> socketWrapper, SocketEvent event, boolean dispatch) {
        try {
            if (socketWrapper == null) {
                return;
            }
            
            NioChannel socket = socketWrapper.getSocket();
            if (socket == null) {
                return;
            }
            
            // 处理套接字事件
            if (event == SocketEvent.OPEN_READ) {
                processSocketRead(socketWrapper);
            } else if (event == SocketEvent.OPEN_WRITE) {
                processSocketWrite(socketWrapper);
            } else if (event == SocketEvent.CONNECT) {
                processSocketConnect(socketWrapper);
            } else if (event == SocketEvent.DISCONNECT) {
                processSocketDisconnect(socketWrapper);
            }
        } catch (Exception e) {
            log.error("Error processing socket", e);
        }
    }
}

9.3.2 NioEndpoint 分析

NioEndpoint 类结构
java 复制代码
// NioEndpoint 类
public class NioEndpoint extends AbstractJsseEndpoint<NioChannel> {
    private Selector selector = null;
    private Acceptor<SocketChannel> acceptor = null;
    private Poller[] pollers = null;
    private int pollerThreadCount = 1;
    private int pollerThreadPriority = Thread.NORM_PRIORITY;
    private long selectorTimeout = 1000L;
    
    @Override
    protected void startInternal() throws Exception {
        // 1. 创建选择器
        selector = Selector.open();
        
        // 2. 创建轮询器
        pollers = new Poller[pollerThreadCount];
        for (int i = 0; i < pollerThreadCount; i++) {
            pollers[i] = new Poller();
            pollers[i].setName("http-nio-8080-Poller-" + i);
            pollers[i].setPriority(pollerThreadPriority);
            pollers[i].setDaemon(true);
            pollers[i].start();
        }
        
        // 3. 创建接受器
        acceptor = new Acceptor<SocketChannel>();
        acceptor.setName("http-nio-8080-Acceptor-0");
        acceptor.setPriority(acceptorThreadPriority);
        acceptor.setDaemon(true);
        acceptor.start();
        
        // 4. 设置状态
        setState(LifecycleState.STARTED);
    }
    
    @Override
    protected void stopInternal() throws Exception {
        // 1. 设置状态
        setState(LifecycleState.STOPPING);
        
        // 2. 停止接受器
        if (acceptor != null) {
            acceptor.stop();
        }
        
        // 3. 停止轮询器
        if (pollers != null) {
            for (Poller poller : pollers) {
                poller.stop();
            }
        }
        
        // 4. 关闭选择器
        if (selector != null) {
            selector.close();
        }
        
        // 5. 设置状态
        setState(LifecycleState.STOPPED);
    }
}
接受器实现
java 复制代码
// 接受器实现
public class Acceptor<U> extends AbstractEndpoint.Acceptor<U> {
    @Override
    public void run() {
        while (endpoint.isRunning()) {
            try {
                // 1. 接受连接
                U socket = endpoint.serverSocketAccept();
                
                // 2. 设置非阻塞模式
                if (socket instanceof SocketChannel) {
                    ((SocketChannel) socket).configureBlocking(false);
                }
                
                // 3. 注册到轮询器
                endpoint.getPoller0().register(socket);
                
            } catch (Exception e) {
                log.error("Error accepting connection", e);
            }
        }
    }
}
轮询器实现
java 复制代码
// 轮询器实现
public class Poller implements Runnable {
    private final Selector selector;
    private final AtomicBoolean running = new AtomicBoolean(true);
    
    public Poller() throws IOException {
        this.selector = Selector.open();
    }
    
    @Override
    public void run() {
        while (running.get()) {
            try {
                // 1. 等待事件
                int keyCount = selector.select(selectorTimeout);
                
                if (keyCount > 0) {
                    // 2. 处理就绪的通道
                    Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                    while (iterator.hasNext()) {
                        SelectionKey key = iterator.next();
                        iterator.remove();
                        
                        // 3. 处理 I/O 事件
                        processKey(key);
                    }
                }
            } catch (Exception e) {
                log.error("Error in poller", e);
            }
        }
    }
    
    private void processKey(SelectionKey key) {
        if (key.isReadable()) {
            // 处理读事件
            processSocketRead(key);
        } else if (key.isWritable()) {
            // 处理写事件
            processSocketWrite(key);
        }
    }
}

9.4 Container 生命周期与 Pipeline/Valve 机制

9.4.1 Container 生命周期

Lifecycle 接口
java 复制代码
// Lifecycle 接口
public interface Lifecycle {
    void addLifecycleListener(LifecycleListener listener);
    void removeLifecycleListener(LifecycleListener listener);
    LifecycleListener[] findLifecycleListeners();
    void start() throws LifecycleException;
    void stop() throws LifecycleException;
    LifecycleState getState();
    String getStateName();
}
生命周期状态
java 复制代码
// 生命周期状态
public enum LifecycleState {
    NEW(false, null),
    INITIALIZING(false, "before_init"),
    INITIALIZED(false, "after_init"),
    STARTING_PREP(false, "before_start"),
    STARTING(true, "configure_start"),
    STARTED(true, "after_start"),
    STOPPING_PREP(true, "before_stop"),
    STOPPING(false, "configure_stop"),
    STOPPED(false, "after_stop"),
    FAILED(false, null),
    DESTROYING(false, "before_destroy"),
    DESTROYED(false, "after_destroy"),
    MUST_STOP(true, null),
    MUST_DESTROY(false, null);
}

9.4.2 Pipeline/Valve 机制

Pipeline 接口
java 复制代码
// Pipeline 接口
public interface Pipeline {
    Valve getBasic();
    void setBasic(Valve valve);
    void addValve(Valve valve);
    void removeValve(Valve valve);
    Valve[] getValves();
    Valve getFirst();
    Valve getLast();
}
Valve 接口
java 复制代码
// Valve 接口
public interface Valve {
    Valve getNext();
    void setNext(Valve valve);
    void invoke(Request request, Response response) throws IOException, ServletException;
    String getInfo();
}
标准 Pipeline 实现
java 复制代码
// 标准 Pipeline 实现
public class StandardPipeline implements Pipeline {
    private Valve first = null;
    private Valve basic = null;
    private Container container = null;
    
    @Override
    public void addValve(Valve valve) {
        if (valve == null) {
            return;
        }
        
        if (first == null) {
            first = valve;
            valve.setNext(basic);
        } else {
            Valve current = first;
            while (current.getNext() != basic) {
                current = current.getNext();
            }
            current.setNext(valve);
            valve.setNext(basic);
        }
    }
    
    @Override
    public void removeValve(Valve valve) {
        if (valve == null) {
            return;
        }
        
        if (first == valve) {
            first = valve.getNext();
        } else {
            Valve current = first;
            while (current != null && current.getNext() != valve) {
                current = current.getNext();
            }
            if (current != null) {
                current.setNext(valve.getNext());
            }
        }
    }
    
    @Override
    public void invoke(Request request, Response response) throws IOException, ServletException {
        if (first != null) {
            first.invoke(request, response);
        } else if (basic != null) {
            basic.invoke(request, response);
        }
    }
}

9.5 自定义 Valve 实现

9.5.1 自定义 Valve 接口

自定义 Valve 实现
java 复制代码
// 自定义 Valve 实现
public class CustomValve extends ValveBase {
    
    @Override
    public void invoke(Request request, Response response) throws IOException, ServletException {
        // 1. 记录请求信息
        String requestURI = request.getRequestURI();
        String remoteAddr = request.getRemoteAddr();
        long startTime = System.currentTimeMillis();
        
        // 2. 调用下一个阀门
        getNext().invoke(request, response);
        
        // 3. 记录响应信息
        long endTime = System.currentTimeMillis();
        long responseTime = endTime - startTime;
        
        log.info("Request: {} from {} took {}ms", requestURI, remoteAddr, responseTime);
    }
    
    @Override
    public String getInfo() {
        return "CustomValve/1.0";
    }
}
注册自定义 Valve
java 复制代码
// 注册自定义 Valve
@Configuration
public class ValveConfig {
    
    @Bean
    public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
        return new TomcatEmbeddedServletContainerFactory() {
            @Override
            protected void postProcessContext(Context context) {
                // 添加自定义阀门
                context.addValve(new CustomValve());
            }
        };
    }
}

9.5.2 访问日志 Valve

访问日志 Valve 实现
java 复制代码
// 访问日志 Valve 实现
public class AccessLogValve extends ValveBase {
    private String directory = "logs";
    private String prefix = "access_log";
    private String suffix = ".txt";
    private String pattern = "%h %l %u %t \"%r\" %s %b";
    private boolean resolveHosts = false;
    
    @Override
    public void invoke(Request request, Response response) throws IOException, ServletException {
        // 1. 调用下一个阀门
        getNext().invoke(request, response);
        
        // 2. 记录访问日志
        logAccess(request, response);
    }
    
    private void logAccess(Request request, Response response) {
        try {
            // 1. 格式化日志
            String logEntry = formatLogEntry(request, response);
            
            // 2. 写入日志文件
            writeLogEntry(logEntry);
        } catch (Exception e) {
            log.error("Error logging access", e);
        }
    }
    
    private String formatLogEntry(Request request, Response response) {
        StringBuilder logEntry = new StringBuilder();
        
        // 解析模式
        String[] patterns = pattern.split(" ");
        for (String pattern : patterns) {
            if (pattern.equals("%h")) {
                logEntry.append(request.getRemoteAddr()).append(" ");
            } else if (pattern.equals("%l")) {
                logEntry.append("- ");
            } else if (pattern.equals("%u")) {
                logEntry.append(request.getRemoteUser() != null ? request.getRemoteUser() : "-").append(" ");
            } else if (pattern.equals("%t")) {
                logEntry.append("[").append(new Date().toString()).append("] ");
            } else if (pattern.equals("\"%r\"")) {
                logEntry.append("\"").append(request.getMethod()).append(" ").append(request.getRequestURI()).append(" ").append(request.getProtocol()).append("\" ");
            } else if (pattern.equals("%s")) {
                logEntry.append(response.getStatus()).append(" ");
            } else if (pattern.equals("%b")) {
                logEntry.append(response.getContentLength()).append(" ");
            }
        }
        
        return logEntry.toString();
    }
}

9.6 自定义 Filter 实现

9.6.1 自定义 Filter 接口

自定义 Filter 实现
java 复制代码
// 自定义 Filter 实现
@Component
public class CustomFilter implements Filter {
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化过滤器
        log.info("CustomFilter initialized");
    }
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        // 1. 前置处理
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        
        // 2. 设置响应头
        httpResponse.setHeader("X-Custom-Header", "Custom Value");
        
        // 3. 调用下一个过滤器
        chain.doFilter(request, response);
        
        // 4. 后置处理
        log.info("Request processed: {}", httpRequest.getRequestURI());
    }
    
    @Override
    public void destroy() {
        // 销毁过滤器
        log.info("CustomFilter destroyed");
    }
}
注册自定义 Filter
java 复制代码
// 注册自定义 Filter
@Configuration
public class FilterConfig {
    
    @Bean
    public FilterRegistrationBean<CustomFilter> customFilter() {
        FilterRegistrationBean<CustomFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(new CustomFilter());
        registration.addUrlPatterns("/*");
        registration.setName("CustomFilter");
        registration.setOrder(1);
        return registration;
    }
}

9.6.2 安全 Filter 实现

安全 Filter 实现
java 复制代码
// 安全 Filter 实现
@Component
public class SecurityFilter implements Filter {
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        
        // 1. 检查请求来源
        String remoteAddr = httpRequest.getRemoteAddr();
        if (!isAllowedAddress(remoteAddr)) {
            httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
            return;
        }
        
        // 2. 设置安全头
        httpResponse.setHeader("X-Content-Type-Options", "nosniff");
        httpResponse.setHeader("X-Frame-Options", "DENY");
        httpResponse.setHeader("X-XSS-Protection", "1; mode=block");
        httpResponse.setHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains");
        
        // 3. 调用下一个过滤器
        chain.doFilter(request, response);
    }
    
    private boolean isAllowedAddress(String remoteAddr) {
        // 检查 IP 地址是否在允许列表中
        return true; // 简化实现
    }
}

9.7 源码调试技巧

9.7.1 调试环境配置

远程调试配置
bash 复制代码
# 远程调试参数
export JAVA_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005"
调试参数说明
参数 说明
-Xdebug 启用调试模式 固定值
-Xrunjdwp 启用 JDWP 协议 固定值
transport 传输方式 dt_socket
server 服务器模式 y
suspend 启动时是否挂起 n
address 调试端口 5005

9.7.2 断点设置技巧

关键断点位置
java 复制代码
// 关键断点位置
public class DebugPoints {
    
    // 1. Bootstrap 启动
    public static void main(String args[]) {
        // 断点:Bootstrap.main()
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.init();
        bootstrap.start();
    }
    
    // 2. Catalina 启动
    public void start() throws Exception {
        // 断点:Catalina.start()
        if (getServer() == null) {
            load();
        }
        getServer().start();
    }
    
    // 3. 请求处理
    public void invoke(Request request, Response response) throws IOException, ServletException {
        // 断点:Container.invoke()
        // 处理请求逻辑
    }
    
    // 4. Servlet 调用
    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        // 断点:Servlet.service()
        // 处理业务逻辑
    }
}

9.7.3 日志调试技巧

调试日志配置
properties 复制代码
# 调试日志配置
org.apache.catalina.level = DEBUG
org.apache.coyote.level = DEBUG
org.apache.tomcat.level = DEBUG
org.apache.catalina.startup.level = DEBUG
org.apache.catalina.core.level = DEBUG
org.apache.catalina.session.level = DEBUG
org.apache.catalina.connector.level = DEBUG
org.apache.catalina.valves.level = DEBUG
自定义调试日志
java 复制代码
// 自定义调试日志
public class DebugLogger {
    private static final Logger log = LoggerFactory.getLogger(DebugLogger.class);
    
    public void logRequest(Request request, Response response) {
        if (log.isDebugEnabled()) {
            log.debug("Request: {} {} from {}", 
                    request.getMethod(), 
                    request.getRequestURI(), 
                    request.getRemoteAddr());
        }
    }
    
    public void logResponse(Request request, Response response) {
        if (log.isDebugEnabled()) {
            log.debug("Response: {} {} in {}ms", 
                    response.getStatus(), 
                    response.getContentLength(), 
                    System.currentTimeMillis() - request.getStartTime());
        }
    }
}

9.8 本章小结

关键要点

  1. 启动入口分析

    • Bootstrap 启动类的作用和实现
    • Catalina 启动类的生命周期管理
    • 服务器创建和初始化过程
  2. 核心类分析

    • StandardServer 的服务管理
    • StandardService 的连接器管理
    • StandardEngine 的请求路由
  3. Coyote 通信模块

    • Http11NioProtocol 的协议处理
    • NioEndpoint 的 I/O 事件处理
    • 连接器和轮询器的工作机制
  4. Container 生命周期

    • Lifecycle 接口的状态管理
    • Pipeline/Valve 机制的工作原理
    • 标准 Pipeline 的实现方式
  5. 自定义组件

    • 自定义 Valve 的实现和注册
    • 自定义 Filter 的实现和配置
    • 安全 Filter 的实现技巧
  6. 源码调试技巧

    • 远程调试环境配置
    • 关键断点设置位置
    • 调试日志配置技巧

学习建议

  1. 源码阅读

    • 从启动入口开始阅读
    • 理解核心类的职责和关系
    • 掌握关键流程的实现细节
  2. 实践练习

    • 实现自定义 Valve
    • 开发自定义 Filter
    • 调试 Tomcat 启动过程
  3. 扩展开发

    • 基于 Tomcat 开发自定义组件
    • 实现性能监控和诊断功能
    • 开发安全防护组件

下一步学习

在下一章中,我们将深入探讨 Tomcat 的性能测试与实战案例,了解如何使用各种工具进行性能测试,分析测试结果,以及在实际项目中的应用案例。


相关资源

相关推荐
野生技术架构师3 小时前
为什么 idea 建议去掉 StringBuilder,使用“+”拼接字符串
1024程序员节
爱学习的大牛1233 小时前
使用C++开发Android .so库的优势与实践指南
android·.so·1024程序员节
bug攻城狮4 小时前
SaaS多租户架构实践:字段隔离方案(共享数据库+共享Schema)
mysql·架构·mybatis·springboot·1024程序员节
brave_zhao4 小时前
达梦数据库,子查询作为删除条件的sql案例,使用了mybatis批量删除
1024程序员节
爬山算法4 小时前
Redis(80)如何解决Redis的缓存穿透问题?
1024程序员节
007php0074 小时前
京东面试题解析:同步方法、线程池、Spring、Dubbo、消息队列、Redis等
开发语言·后端·百度·面试·职场和发展·架构·1024程序员节
小丁爱养花4 小时前
Redis 内部编码/单线程模型/string
数据库·redis·缓存·1024程序员节
小二_沏杯二锅头4 小时前
CentOS7.9部署Mysql8(二进制方式)
1024程序员节
萧寂1734 小时前
vue导出数据到excel
1024程序员节