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

posted on   荣锋亮  阅读(463)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2021-02-20 golang 几种 filter的实现包
2021-02-20 dremio 节点监控
2021-02-20 dremio 升级操作说明

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示