去年从深圳辞职后,由于疫情原因玩了挺长一段时间,现在准备换个城市找新工作了。
其实以前才开始流行注解配置项目时就看过这些源码了,可能由于懒惰吧,没有留下只言片语。
现在写篇文章查遗备缺,也便各位做个交流。
注解的自启动基于Servlet3.0的检测与调用
首先我们来看AbstractAnnotationConfigDispatcherServletInitializer这个抽象类,一般我们的启动都需要继承这个类,并实现其抽象方法。
从本类的方法看,主要都是protected和abstract的方法,所以调用的地方都在父类。
从类的承继关系图再加代码的寻根索迹。
从名称来看理当是调用onStartup方法,可这依然不是真实的调用点。
通过IDE的调用查找工具和下方的注释可以看出
Interface to be implemented in Servlet 3.0+ environments in order to configure the ServletContext programmatically -- as opposed to (or possibly in conjunction with) the traditional web.xml-based approach.
Implementations of this SPI will be detected automatically by SpringServletContainerInitializer, which itself is bootstrapped automatically by any Servlet 3.0 container. See its Javadoc for details on this bootstrapping mechanism.
最终是由Servlet的容器通过SPI的方式获取SpringServletContainerInitializer这个类的class信息,并且通过@HandlesTypes注解获取WebApplicationInitializer接口的实现类,并作为参数调用SpringServletContainerInitializer的onStartup方法
根据Java的动态绑定规则,其调用的是AbstractDispatcherServletInitializer的onStartup方法,跟踪代码会发现AbstractAnnotationConfigDispatcherServletInitializer的createRootApplicationContext就是启动时创造ApplicationContext并进而BeanFactory的地方。
这就是自启动的代码简单分析的内容了。
Bean的查找和load是个复杂的过程,现在复习实在没时间写那么长的文章了,补个链接给大家参考,他山之石的确不错。