跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • springboot 中 controller 中通过一个 key 值动态调用 service
未分類
30 8 月 2020

springboot 中 controller 中通过一个 key 值动态调用 service

springboot 中 controller 中通过一个 key 值动态调用 service

資深大佬 : jiobanma 6

想在服务启动的时候,将所有的 service 存放到一个缓存 Map 中,然后给定一个 key 值绑定。 在 controller 中通过 key 值找到对应的 service 对象该如何实现。 因为不同 service 的类型不一样,所以 Map 在定义的时候只能定义成 Map<String,Object>value 是个 Object, 这样的话通过 key 值取出来的也就是 Object 的类型,无法调用到 service 下的方法。 有没有好的实现思路呢?

大佬有話說 (49)

  • 資深大佬 : tsening

    我累了,小白吧。。。

  • 資深大佬 : mosliu

    反射呗

  • 資深大佬 : chendy

    为啥要这么搞,别的不说,service 的参数和返回也不一样啊

  • 主 資深大佬 : jiobanma

    @chendy #3 因为服务要做成动态的,service 里面只有一个通用接口,参数都是 Map 所以不存在返回值类型和参数不同的问题

  • 資深大佬 : wysnylc

    @jiobanma #4 我只能说,作死
    说了多少回参数和返回值不要用 map,不撞南墙不回头

  • 資深大佬 : pushback

    method.invoke

  • 資深大佬 : pushback

    存储 class 就行,对应 value 到 BeanFactory 下去取

  • 資深大佬 : idoggy

    入参都一样吗?要调用的 service 全部继承同一个接口就行了,用 applicationcontext.getbean 去调。

  • 資深大佬 : ily433664

    通过 applicationContext 获取,可以根据 bean 类型或者名称

  • 資深大佬 : YzSama

    @idoggy #8 这个方式可取。 不过,入参和出参不建议使用 map 。

  • 資深大佬 : lipcao

    哈哈,你这个标准的策略+工厂模式 解决 if else 啊,前一段时间公众号嗷嗷推这个。。。

  • 資深大佬 : zhuweiyou

    建议主学 PHP 或 JS,他们就是这么玩的。

  • 資深大佬 : DelayNoMay

    用 golang 的 interface

  • 資深大佬 : yuan7712

    groovy https://www.jianshu.com/p/c7803626c09d

  • 資深大佬 : 460881773

    花里胡哨

  • 資深大佬 : aguesuka

    service 都带个 controller,原来的 controller 里通过 key 转发到对应的 service 的 controller 。param bind 是 spring 的工作,不要实现一个低配版的

  • 資深大佬 : aguesuka

    以前我还是个傻逼的时候,map 里面存的是个 lambda 函数,比如 map.put(key,xxxxService::doxxxxxxx)

  • 資深大佬 : huifer

    添加一个 接口比如
    “`java
    public interface KeyInterface{
    String key();
    }

    “`
    – 所有 service 都实现这个接口,重写 key()

    – 在启动阶段(ApplicationRunner 或者 CommandLineRunner)通过 context.getBeanOfTypes(KeyInterface.class) 获取到一个 map
    key: beanName value: KeyInterface 的实现
    – 调用 value 的 key()方法. 将结果映射成 key:key() ,value: service 即可

  • 資深大佬 : dutianze

    如果所有 sevice 都是同样的接口的话,

    1. 所有 service 都继承一个接口 CommonService

    2.
    @Autowired
    private Map<String, CommonService> commonServiceMap;

    k 默认是 service 的类名小写,v 默认是对应的 service

  • 資深大佬 : butterfly1211

    服务注册与服务发现

  • 資深大佬 : 24bit

    不如直接用注解标注要缓存的方法,直接在 Map 里面存 Method,取的时候直接调用

  • 資深大佬 : Cyron

    Service service = applicationContext.getBean(“serviceImplA”);
    Service service = applicationContext.getBean(“serviceImplB”);

  • 資深大佬 : jintianfengda

    用 map 这么玩开发一时爽,维护火葬场

  • 資深大佬 : ixx

    可以参考一下 : https://jianpage.com/2019/06/26/square3/

  • 資深大佬 : liuguangcuican

    定义一个 interface,在其每个实现类上使用 @Component(“实现类的别名”)。在 controller 里使用 @Autowrid 定义一个 Map<String,你定义的 interface>,在入口方法里使用 map.get(“实现类的别名”)就能获取到你对应的实现类。

  • 資深大佬 : d460686680

    实现同一个接口 + getBean()

  • 資深大佬 : levizheng

    简单工厂就可以解决了。。 放一 map 里

  • 資深大佬 : xuanbg

    我司的 php 写的老系统就是这样,接口参数里面有个 action,1234567……分别对应一个方法。。。。各方法传入一个 object,其实就是一个 json,各个方法自己负责解析这个参数。主莫非要的是这个?

    可是为啥不把接口拆开呢?

  • 資深大佬 : KevinBlandy

    ApplicationContext.getBean();

  • 資深大佬 : ocean1477

    策略模式了解下

  • 資深大佬 : caotian

    不要手工维护 map, 不然每次加一个 serivce 还要修改这个 map
    可以这样试试: 每个 service 定义自己的 key, 实现同一个接口 IService, 使用的时候通过 Autowired 注入拿到 List<IService>对象, 通过 key 来获得具体的 service 实例, 再调用方法

  • 主 資深大佬 : jiobanma

    @wysnylc #5 业务需要

  • 資深大佬 : pierswu

    这个用 mvc 的 forward 不就行了吗?

    每一个 service 都有各自的 controller,就按照正常的写 ,然后总的 controller 根据不同的 key,forward 到不同的 controller
    至于 key,最好能放在 url 中或者 header 中,好取一些

  • 資深大佬 : pierswu

    用 forward 的话,每个 service 的参数类型,参数个数,返回值,都可以不一样的

  • 資深大佬 : pengfei

    策略模式 ?

  • 資深大佬 : venpong

    建议学学设计模式,比如上说的策略模式就可以很优雅的解决你这个问题。

  • 資深大佬 : oneisall8955

    我最喜欢搞这些花里胡哨得了,经常写工厂模式+模板

  • 資深大佬 : securityCoding

    applicationContext.getBean()

    策略模式+泛型可解

    不过在业务层做这种事情这种看起来很无脑….中间件还情有可原

  • 資深大佬 : BigBunny

    做那种对外开放平台标准化接口有用过。当时的想法是 controller 里所有接口的请求参数返回参数都一样。加签验签逻辑也都一致。索性共用一个接口,调用 service 里的方法通过自定义注解去区分。半路转的 java,也不知道这么做了对不对好不好。

  • 資深大佬 : supermoonie

    注解?

  • 資深大佬 : chachae

    策略模式

  • 資深大佬 : gaius

    以前掉各种银行接口就是用反射,配置全限定名

  • 資深大佬 : 1ffree

    19l 正解 +1

  • 資深大佬 : HolmLoh

    工厂模式加模板模式,小的单人开发的项目这么搞搞还行,偷偷懒还挺快乐,人多起来不好维护

  • 資深大佬 : yisheyuanzhang

    想到两种方法
    1 、8L 的方法,Service 实现同一接口,key 作为 bean 的名称,用 applicationcontext.getbean 去调。缺点是每个 service 只能实现同一个方法。
    2 、定义 service 的类注解和方法注解, 启动时通过 BeanPostProcessor,根据类注解的 key 存入 Map<key,bean>中。调用时根据类注解 key,找到 bean,根据方法注解 key 找到方法,通过反射执行

    我们生产中用过第二种

  • 資深大佬 : CoderGeek

    简单点
    1. <String,String> key 是你的策略 value 是你的 beanName 直接 get 就好
    2. <String,Class> key 是你的策略 value 是你的所有加载的 service 取出来强制转型
    3.直接用 xml 更简单创建一个 map 对象 value 是多个 bean
    举个常见栗子
    private Map<Object, Object> targetDataSources;
    <bean id=”xxx” class=”xxxxx”>
    <property name=”targetDataSources”>
    <map>
    <entry key=”xxxxx” value-ref=”xxxxx”></entry>
    </map>
    </property>
    </bean>

  • 資深大佬 : xgfan

    别听上 BB 。
    把那些 service 合成一个函数方法就 ok 了。
    一个函数就解决所有问题了,高内聚。
    传来 map,返回 map,改动也只需要改这一个函数,低耦合。

  • 資深大佬 : xiaoxinshiwo

    instance of

  • 資深大佬 : yazinnnn

    “`kotlin
    @RestController
    class ControllerA(
    var serviceA: ServiceA,
    var serviceB: ServiceB
    ) {

    @RequestMapping(“/”)
    fun foo(type: String, param: String) = serviceMap[type]!!(param)

    private val funcA = { it: String -> serviceA.foo(it) }
    private val funcB = { it: String -> serviceB.foo(it) }

    private val serviceMap by lazy {
    mutableMapOf(
    “a” to funcA,
    “b” to funcB
    )
    }
    }
    “`

    kotlin 可以这么干,java 没有 by lazy,估计比较啰嗦

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具