分析笔记(二):RESTEASY-828 Issue with injected ServletContext in Resteasy/SpringMVC setup
尝试自己注入httpServlet至ResteasyContext。
ResteasyContext的设计:

ResteasyContext在resteasy当中的使用位置:

在对resteasy-spring模块的分析完成之后,发现没有地方通过ResteasyContext保存servletContext。
写一个MyServletRequestListener:

它实现了javax.servlet.ServletRequestListener接口:

使用「debug」模式启动服务:

在「IntelliJ」里面加载项目,分析启动过程,第一次启动的时候,会触发ResteasyDeploymentImpl的start()方法:

这个逻辑定义在resteasy-spring提供的springmvc-resteasy.xml里面:

ResteasyDeploymentImpl初始化完成后,接着初始化依赖ResteasyDeploymentImpl的SpringBeanProcessor:

上面是初始化过程。总结一下,springmvc-resteasy.xml里面定义的几个「bean」如下:
ResteasyDeploymentDispatcherRegistryProviderFactory
此外,注意到Dispatcher,Registry,ProviderFactory。最后,SpringBeanProcess在初始化过程使用ResteasyDeploymentImpl(是ResteasyDeployment的接口实现)。
下面是SpringBeanProcessor的初始化过程截图:

查看上面断点停下来时候的「stacktrace」,看到几个beans对应的实际instances:

如上面截图所示,分别是:
ResteasyDeploymentImplResourceMethodRegistrySynchronousDispatcherResteasyProviderFactoryImpl
综合上面的分析,相关的classes组成如下:

接下来继续分析服务的启动过程:SpringBeanProcessor和相关的beans初始化完成后,就要处理用户的请求,此时走的是ResteasyHandlerAdapter的handle()方法:

上面这个handle()方法,是用户每次请求都要执行的,是处理请求的入口。
继续往下执行,注意因为这是第一次启动,虽然MyServletRequestListener工作了,但是注入servletContext失败:

初步分析,是因为第一次访问的时候,springmvc-resteasy.xml的加载是「lazily initialized」的,所以里面的ResteasyDeploymentImpl和其它组件都是会在「第一次启动」执行,而后续访问都是直接走,所以应该在MyServletRequestListener的执行次序方面有一些冲突。
后续可以通过多次访问来验证这点:

可以看到后续的访问都不再报错了。而且只走ResteasyHandlerAdapter的handle()方法:

以上是对问题的分析记录,有了上面的基础,后续的工作是给出解决方案。