简单看了看写了些,Spring最简单的一个实现,实现了什么具体如下

一、 初始化阶段
| 步骤序号 | 初始化阶段 | 核心方法 | 主要作用 | 关键数据结构变化 |
|---|---|---|---|---|
| 1 | 加载配置文件 | doLoadConfig() |
读取 contextConfigLocation 指定的配置文件(如 application.properties) |
contextConfig 中加载 scanPackage |
| 2 | 包扫描 | doScanner() |
根据 scanPackage 扫描所有 .class 文件 |
classNames 保存所有全限定类名 |
| 3 | IoC 实例化 | doInstance() |
对 @GPController、@GPService 标注的类进行实例化 |
ioc 中放入 Bean 实例 |
| 4 | 依赖注入(DI) | doAutowired() |
给 @GPAutowired 字段注入依赖 |
ioc 内对象完成属性赋值 |
| 5 | 初始化映射关系 | doInitHandlerMapping() |
建立 URL → Method 的映射关系 | handlerMapping 填充 |
| 6 | 初始化完成 | init() 结束 |
框架启动完成,可接收请求 | MVC 框架可工作 |
doLoadConfig


扫描相关类

IoC 实例化
String className : classNames
来我自己聊聊
注解扫描
GPController
clazz 反射实例化,然后添加进容器,name 和calss
GPService
@GPService 获取value
如果有,优选name
2.正常注入
3.接口获取
2️⃣ 为什么要把接口也放进 IOC?
这一步的目的只有一个:@GPAutowired
private UserService userService;
key = "com.xxx.UserService"
value = UserServiceImpl 的实例
private void doInstance() {
if(classNames.isEmpty()){return;}
try {
for (String className : classNames) {
Class<?> clazz = Class.forName(className);
if(clazz.isAnnotationPresent(GPController.class)) {
//key提取出来了,把value也搞出来
String beanName = toLowerFirstCase(clazz.getSimpleName());
Object instance = clazz.newInstance();
ioc.put(beanName, instance);
}else if(clazz.isAnnotationPresent(GPService.class)){
//1、在多个包下出现相同的类名,只能寄几(自己)起一个全局唯一的名字
//自定义命名
String beanName = clazz.getAnnotation(GPService.class).value();
if("".equals(beanName.trim())){
beanName = toLowerFirstCase(clazz.getSimpleName());
}
//2、默认的类名首字母小写
Object instance = clazz.newInstance();
ioc.put(beanName, instance);
//3、如果是接口
//判断有多少个实现类,如果只有一个,默认就选择这个实现类
//如果有多个,只能抛异常
for (Class<?> i : clazz.getInterfaces()) {
if(ioc.containsKey(i.getName())){
throw new Exception("The " + i.getName() + " is exists!!");
}
ioc.put(i.getName(),instance);
}
}else{
continue;
}
}
}catch (Exception e){
e.printStackTrace();
}
}
依赖注入
思路
扫描bean下的,方法,是否有对应注解,如果有,那么根据ioc容器的类型名字拿取bean
然后反射bean下的变量进行set

初始化HandlerMapping
映射,拿取conroller的注解,拿取method上的注解,拿出url 。然后映射,url对应method。

public class GPDispatchServlet extends HttpServlet
HttpServlet 是 Java EE(Jakarta EE)中提供的HTTP 协议专用 Servlet 基类,它封装了对 HTTP 请求的处理逻辑。GPDispatchServlet 继承 HttpServlet 的核心作用是复用 HttpServlet 提供的成熟 Web 请求处理骨架,无需从零实现 Servlet 的底层规范,直接获得处理 HTTP GET/POST 等请求的能力。
在这份手写简易 Spring MVC 框架的代码中,GPDispatchServlet 并非一个普通的 Servlet,而是整个 MVC
框架的核心前端控制器(Front Controller),这是一种经典的设计模式应用。 它的核心职责是统一接收所有客户端的 HTTP
请求,作为请求入口的 "总闸门",再将请求分发给对应的业务处理组件(如 DemoAction 中的具体方法),而非为每个业务功能创建单独的
Servlet。
委派
思路,继承servlet
获取前端控制器,写doget 和post 写调用器
作用
拿取request的url,跟urlmap进行对应。如果对应上。那么进入执行
1.参数处理
2.根据method拿去calss的名字,然后进行反射invoke

url对应
http://localhost:8080/gupaoedu_vip_spring_war/demo/query?name=Jerry
params = {ParameterMap@3166} size = 1
"name" -> {String[1]@3173} ["Jerry"]
很有意思的参数处理


GPRequestParam
运行

控制器
