基于注解的请求分发器:BirdBoot框架核心组件解析
package com.birdboot.core;
import com.birdboot.annotation.Controller;
import com.birdboot.annotation.RequestMapping;
import com.birdboot.http.HttpServletRequest;
import com.birdboot.http.HttpServletResponse;
import java.io.File;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
public class DispatcherServlet {
private static DispatcherServlet instance = new DispatcherServlet();
private DispatcherServlet() {
}
public static DispatcherServlet getInstance() {
return instance;
}
private static File baseDir;
private static File staticDir;
static {
try {
baseDir = new File(
ClientHandler.class.getClassLoader().getResource('.').toURI()
);
staticDir = new File(baseDir, 'static');
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
public void service(HttpServletRequest request, HttpServletResponse response) throws Exception {
String path = request.getRequestURI();
System.out.println('请求的抽象路径是:' + path);
// 1. 扫描controller包下的所有类
File dir = new File(baseDir, 'com/birdboot/controller');
File[] subs = dir.listFiles(f -> f.getName().endsWith('.class'));
for (File sub : subs) {
String className = sub.getName().replace('.class', '');
// 加载对应类对象时,包名固定:com.birdboot.controller
Class<?> cls = Class.forName('com.birdboot.controller.' + className);
// 2. 查看哪些被注解@Controller标注的过的类(只有被该注解标注的类才认可为业务处理类)
if (cls.isAnnotationPresent(Controller.class)) {
Object obj = cls.newInstance();
Method[] methods = cls.getMethods();
// 3. 遍历这些类,并获取他们的所有方法,并查看哪些是业务方法
for (Method method : methods) {
// 只有被注解@RequestMapping标注的方法才是业务方法
if (method.isAnnotationPresent(RequestMapping.class)) {
// 4. 遍历业务方法时比对该方法上@RequestMapping中传递的参数值是否与本次请求
// 路径path值一致?如果一致则说明本次请求就应当由该方法进行处理
// 因此利用反射机制调用该方法进行处理。
// 提示:反射调用后要记得return,避免执行后续处理静态资源的操作
method.invoke(obj, path, request.getQueryString());
return; // 处理完业务方法后直接返回
}
}
}
}
// 5. 如果扫描了所有的Controller中所有的业务方法,均未找到与本次请求匹配的路径
// 则说明本次请求并非处理业务,那么执行下面请求静态资源的操作
File file = new File(staticDir, path);
if (file.isFile()) {
response.setStatusCode(200);
response.setStatusReason('OK');
response.addHeader('Server', 'BirdServer');
response.setContentFile(file);
} else {
response.setStatusCode(404);
response.setStatusReason('NotFound');
file = new File(staticDir, '404.html');
response.addHeader('Server', 'BirdServer');
response.setContentFile(file);
}
}
}
代码解析:
这段代码定义了 DispatcherServlet 类,它是 BirdBoot 框架的核心组件之一,负责处理 HTTP 请求并将其分发到相应的业务方法。
主要功能:
- 请求分发: 接收 HTTP 请求,并根据请求路径判断是否为业务请求。
- 业务处理: 如果是业务请求,则扫描所有带有
@Controller注解的类,并查找匹配请求路径的@RequestMapping注解方法,然后通过反射机制调用该方法处理请求。 - 静态资源处理: 如果不是业务请求,则将其视为静态资源请求,并返回相应的静态资源文件。
代码优化:
- 使用更清晰的注释解释代码逻辑。
- 将业务处理逻辑与静态资源处理逻辑分开,提高代码可读性。
- 在处理完业务方法后立即返回,避免执行不必要的代码。
总结:
DispatcherServlet 是 BirdBoot 框架的核心组件,它利用注解和反射机制实现了灵活的请求分发功能,是构建 Web 应用程序的重要基础。
原文地址: https://www.cveoy.top/t/topic/B9L 著作权归作者所有。请勿转载和采集!