pf4j 注入spring controller 的几种方法
核心还是基于RequestMappingHandlerMapping bean 进行controller 的创建
方法一
获取RequestMappingHandlerMapping bean 注册registerMapping
参考(参考伪代码)
getMappingForMethod = ReflectionUtils.findMethod(RequestMappingHandlerMapping.class, "getMappingForMethod", Method.class, Class.class);
Controller annotation = aClass.getAnnotation(Controller.class);
if(annotation != null) {
Object bean = <getPluginApplicationContext()>.getBean(aClass); // use parent context( PluginManager)
Method[] methods = aClass.getMethods();
for (Method method : methods) {
if (method.getAnnotation(RequestMapping.class) != null
|| method.getAnnotation(GetMapping.class) != null
|| method.getAnnotation(PostMapping.class) != null) {
RequestMappingInfo requestMappingInfo = (RequestMappingInfo) getMappingForMethod.invoke(requestMappingHandlerMapping, method, aClass);
requestMappingHandlerMapping.registerMapping(requestMappingInfo, bean, method);
}
}
}
方法二
自己实现AbstractHandlerMapping ,注册一个自己的WebMvcRegistrations bean 对于spring boot 可以直接实现WebMvcRegistrations
参考
@Bean
@ConditionalOnMissingBean(WebMvcRegistrations.class)
public WebMvcRegistrations mvcRegistrations() {
return new WebMvcRegistrations() {
@Override
public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
return new <custom>RequestMappingHandlerMapping();
}
@Override
public RequestMappingHandlerAdapter getRequestMappingHandlerAdapter() {
return null;
}
@Override
public ExceptionHandlerExceptionResolver getExceptionHandlerExceptionResolver() {
return null;
}
};
}
自定义RequestMappingHandlerMapping 实现一个基于注解注册controller 的方法,这样在处理阶段就比较方便了
public void registerControllers(SpringBootPlugin springBootPlugin) {
getControllerBeans(springBootPlugin).forEach(bean -> registerController(springBootPlugin, bean));
}
private void registerController(SpringBootPlugin springBootPlugin, Object controller) {
String beanName = controller.getClass().getName();
// unregister RequestMapping if already registered
unregisterController(springBootPlugin.getMainApplicationContext(), controller);
springBootPlugin.registerBeanToMainContext(beanName, controller);
detectHandlerMethods(controller);
}
注意bean 也是注册到main context 基于此方法的好处是能够更好的利用detectHandlerMethods
进行handler 的处理,与上边实际是类似的,但是更加符合spring 的处理机制
说明
对于resource 的处理,我们也可以自己实现一个PathResourceResolver,扩展WebMvcConfigurer
添加一个自己的resourcehandler
default void addResourceHandlers(ResourceHandlerRegistry registry) {
}
sbp 的一些实现是很值得借鉴参考的
参考资料
https://github.com/hank-cp/sbp
https://gitee.com/dianbuapp_admin/jeegot
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
2021-02-20 golang 几种 filter的实现包
2021-02-20 dremio 节点监控
2021-02-20 dremio 升级操作说明