# 造过轮子的人学框架有多快——我自己写完IOC和AOP,Spring就是换个API
造过轮子的人学框架有多快——我自己写完IOC和AOP,Spring就是换个API
文章目录
- 造过轮子的人学框架有多快——我自己写完IOC和AOP,Spring就是换个API
- 背景
- 原理是同一套
- IOC
- AOP
- ORM
- Spring Boot上手有多快
- 真正花时间的不是学框架,是学配置
- 什么不会?
- 总结
背景
书里写了我从2012年开始手写IOC容器(BeanFactory)和轻量AOP(doProxy),跑了14年。有人问:你不用Spring,是不是不会?
不是不会,是不需要。而且反过来——因为我造过IOC和AOP的轮子,学Spring全家桶几乎没费劲。
原理是同一套
IOC
我的BeanFactory三步走:扫描@bean注解→反射实例化→属性注入+路由注册。核心代码300行。
Spring的AbstractApplicationContext.refresh()也是三步走:扫描@Component→反射实例化→依赖注入+代理生成。核心逻辑一样,复杂度高了几十倍。
| 我写的 | Spring做的 | 原理 |
|---|---|---|
Class.forName()+newInstance() | BeanDefinition+ 反射创建 | 一样 |
@propertysetter注入 | @Autowired字段/setter注入 | 一样 |
mothodmapHashMap存路由 | HandlerMapping存路由 | 一样 |
手写的bean.xml解析 | @ComponentScan自动扫描 | 机制不同,原理一样 |
我已经知道IOC要解决什么问题(对象谁来创建、依赖谁注入、路由谁管理),Spring只是把这些用更通用的方式又做了一遍。学Spring IOC就是学"它把我的300行拆成了哪些类"。
AOP
我的doProxy:CGLIB生成代理类→责任链串拦截器→@Trans/@Logger/@monitoring三个注解驱动。
Spring AOP:CGLIB或JDK动态代理→Advisor链→@Transactional/@Async等注解驱动。
一样的。连代理模式都一样——我的transInterceptor在finally里回滚,Spring的@Transactional也在finally里回滚。区别是Spring的拦截器链更灵活,支持切点表达式,我的就是注解顺序决定链顺序。
ORM
我的DBUtil + DataStore状态机:_t字段追踪行状态,save()自动路由insert/update/delete。
Hibernate/MyBatis-Plus:脏检查或注解标记追踪字段状态,save()自动路由。
原理一模一样。Hibernate用CGLIB代理实体做脏检查,我用_t状态机做脏检查。我的方案更土,但更直观——看一眼_t的值就知道这行是新增还是修改,不用追代理类的调用链。
Spring Boot上手有多快
我学Spring Boot的时间线:
第一天:lesson1——IoC容器
@Configuration、@Bean、@Component、@Value、@PropertySource。
看了一遍,这就是我BeanFactory的注解版。AnnotationConfigApplicationContext和我的BeanFactory.init()做的是同一件事。@ComponentScan比我手写目录遍历方便,但原理没区别。
第二天:lesson2——Web应用
@Controller、@RequestMapping、MyBatis Mapper、@Transactional。
@Controller+@RequestMapping就是我@responseMapping的Spring写法。@Transactional就是我@Trans的Spring写法。Servlet注册有两种方式(注解和ServletRegistrationBean),Interceptor通过WebMvcConfigurer注册——比我的route.java硬编码灵活,但做的事情一样。
第三天:lesson3-4——Dubbo RPC
@DubboService提供方、@DubboReference消费方、Zookeeper注册中心。
这就是远程版的IOC——本地调用变成网络调用,对象实例化变成服务发现。注册中心不是新概念,我的框架虽然没有注册中心,但route.java本质上就是一个本地的"服务注册表"——bean名称→bean实例的映射。Dubbo把它变成了网络版。
第四天:Nacos + Feign + Gateway
Nacos服务发现=注册中心+Nacos配置中心=外置配置(我的INI文件的网络版)Feign声明式调用=远程方法调用的注解驱动版Gateway路由=myroute.java的网关版。
全部打通。不是因为我聪明,是因为底层原理我都自己实现过。
真正花时间的不是学框架,是学配置
Spring Boot的注解和原理,我半天就能对应到自己写的代码上。真正花时间的是:
- pom.xml依赖冲突——spring-cloud-alibaba的版本要和spring-boot版本匹配,错一个版本号就启动报错,报错信息还不说版本不兼容,说的是ClassNotFound。这种坑和原理无关,纯经验。
- yml配置层级——Nacos的
bootstrap.yml和application.yml加载顺序不同,配错位置就读不到值。 - 自动配置的黑盒——
@SpringBootApplication背后自动注册了一堆Bean,你不知道它注册了什么,出了问题不知道从哪查。这个反而印证了我自研框架的原则——可控性比功能性重要。
什么不会?
说实话,Spring的高级特性我也没有全用到:
- Spring Security——安全体系我做的管道设计(六道防线),和Spring Security的FilterChain是同一层的东西,但Spring Security的配置复杂度远超我的管道。不过我的场景不需要OAuth2、不需要RBAC的复杂权限模型,所以没深入。
- Spring Cloud全链路——Config、Bus、Sleuth、Hystrix这些,我只用了Nacos+Feign+Gateway。政务单体应用居多,微服务治理的需求不强。
- WebFlux响应式——没碰。政务系统以CRUD为主,阻塞IO够用,响应式带来的复杂度不值得。
但这些都是"没用过",不是"学不会"。原理通了,需要的时候看文档就行。
总结
造过轮子的人学框架有多快?原理层面零成本,只学API和配置。
我的BeanFactory让我秒懂Spring IOC。我的doProxy让我秒懂Spring AOP。我的_t状态机让我秒懂Hibernate脏检查。我的route.java让我秒懂Spring MVC路由和Gateway路由。
不是Spring简单,是自己造过轮子之后,所有框架都是你的轮子的复杂版。你知道它为什么这么设计,因为你也面对过同样的问题,只是你的解法更简单。
反过来说,如果没造过轮子直接学框架,你记住的是API和配置;造过轮子再学框架,你理解的是设计意图。前者出了问题翻文档,后者出了问题能猜到是哪层出了问题。
这大概就是14年自研框架最大的副产品——不是框架本身,是对任何框架都能快速穿透到底层的能力。
相关阅读——文中提到的自研框架实现,每篇都有完整源码:
- Java Web自研框架18年架构决策复盘 —— 全景回顾,从2004年Servlet到2026年仍在运行
