Spring
Spring
有个统一的调度入口:DispatcherServlet
1 | org.springframework.web.servlet.DispatcherServlet#getHandler |
然后通常就会进入到这里:
1 | org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#lookupHandlerMethod |
上面这个是抽象类,实现类应该是:
1 | org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping |
然后路由应该这个属性里(不一定全):
1 | mappingRegistry.registry |
Ver:3.2.0
如果是 3.2.0
版本,要使用 JDK17
,那么想使用反射获取 URL
好像还要加上
1 | --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED |
JDK9
以后加上了这个:
同时,还需要先访问一次任意路由,这样DispatcherServlet
才会进行初始化:
Tomcat
路由信息
1 | org.apache.catalina.connector.CoyoteAdapter#postParseRequest |
断点在这附近:
一个提取路由的脚本:
1 | Object[] o = ((((StandardService)((Connector)((CoyoteAdapter)this).connector).service).mapper).contextObjectToContextVersionMap).entrySet().toArray(); |
Resin
resin 是怎么拿到路由的呢:
首先会在这里:
1 | com.caucho.server.http.HttpRequest#handleRequest |
在此处根据 uri
获取 invocation
:
1 | com.caucho.server.http.AbstractHttpRequest#getInvocation |
首先上面是获取缓存,应该是判断这个路由之前是否被访问过,如果被访问过就会在如下这个 cache
里:
没有的话就会进入到 buildInvocation
,这里进入的是一个 default
的 host
,就是默认的,应该会有别的情况,但是没遇到,就先不记了,一路跟到这里:
1 | com.caucho.server.webapp.WebAppContainer#buildInvocation |
1 | com.caucho.server.webapp.WebAppContainer#getWebAppController |
应该是根据 URI
找控制器:
然后再进一层:
1 | com.caucho.server.webapp.WebAppContainer#findEntryByURI |
首先根据 uri
从 cache
中获取,如果没有的话就再进入 findByURIImpl
,这里写个简单的代码,可以把它导出来:
1 | Object[] xxx= Arrays.stream(this._uriToAppCache._entries).toArray(); |
然后就是 findByURIImpl
:
1 | com.caucho.server.webapp.WebAppContainer#findByURIImpl |
可以看到这里又从 cache 里拿一次,是因为上面最后对 uri
做了一次 normalize
,然后如果还找不到就去 appDeploy
里找(这里应该是部署的应用)。
这个 findController
也是主要从两个地方找:
1 | com.caucho.env.deploy.DeployContainer#findController -> |
主要还是看第二个 generateController
:
如果这里还找不到的话,回到 findByURIImpl
:
此处会往下递归,找到最后一个 /
做截断,然后往下找,可能需求就是要找类似 /*
这样的东西。
resin 路由位置
不过上面的看不太懂,但是我找到一处可以拿到一些 url 的地方(这个地方要在找一个新的 uri 的时候会调用到,所以记得改一下 uri ):
1 | com.caucho.server.dispatch.ServletMapper#mapServlet |
Struts
1 | 测试版本: |
断点可以下在:
1 | com.opensymphony.xwork2.config.impl.DefaultConfiguration.RuntimeConfigurationImpl#findActionConfigInNamespace |