如何实现controller层动态调用多个service类以及方法

Cathy313 2017-11-02 04:52:40
请教大家一个问题:我们最近项目中的业务模块需要调用400多个存储过程,前端业务直接调取存储过程就可以了,现在领导嫌弃存储过程后期维护麻烦,而且之前的人存储过程写的不好,所以要把所有的存储过程内部业务逻辑转化成java实现,用的SpringMVC+mybatis。我原来的想法是每个存储过程写成一个service方法,controller层用反射的方法来调service层,但是由于存储过程太多不可能都写在一个类中,所以根据业务分了模块,大概有20个左右,想法是一个业务模块所涉及到的所有存储过程放在一个service实现类,那么仍然有20个service实现类,如何在controller层动态调用service类呢?或者还有其他更好的方法?(备注:前端不是我们做的,所以我们控制不了)
...全文
5375 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
Cathy313 2017-11-06
  • 打赏
  • 举报
回复
引用 20 楼 r562253897 的回复:
[quote=引用 19 楼 r562253897 的回复:] [quote=引用 17 楼 rhy31328 的回复:] [quote=引用 13 楼 r562253897 的回复:] 1.定义一个接口; 2.20个service作为20个实现类 3.数据库存储过程名换成service实现类的名称; 4.controllor中根据条件获取到service的实现类名,使用spring的ApplicationContext 获取到实现类的实例; 以下只是简单的例子,具体根据你的业务设计

        //通过Spring的方式调用方法
        //构建容器   构建容器的时候就调用了set方法
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");//第1行
        //从容器中获取javaBean的实例   控制反转IOC
        HelloWorld hw1 = (HelloWorld)ac.getBean("hw");
        hw1.sayHello();
你这个方法我有思考过,是不是一个接口,对应多个service?然后一个存储过程写成一个service实体类?这么写的话我得写400个service实现类[/quote] 你是20个service里面,每个实例有很多方法是吧,那你现在的存储过程和方法应该是一对一的吧? 只是不想破坏service的单例,可以在实例上使用spring的实例,method使用反射; 也就是你需要在每个存储过程的位置配置实例名和方法名,才能对应起来。[/quote] 还有一点,你20多个实例都有了,每个里面又20来个方法,那创建400个实例又有什么问题呢。。。。[/quote] 我再思考一下吧,谢谢!
Cathy313 2017-11-03
  • 打赏
  • 举报
回复
引用 13 楼 r562253897 的回复:
1.定义一个接口; 2.20个service作为20个实现类 3.数据库存储过程名换成service实现类的名称; 4.controllor中根据条件获取到service的实现类名,使用spring的ApplicationContext 获取到实现类的实例; 以下只是简单的例子,具体根据你的业务设计

        //通过Spring的方式调用方法
        //构建容器   构建容器的时候就调用了set方法
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");//第1行
        //从容器中获取javaBean的实例   控制反转IOC
        HelloWorld hw1 = (HelloWorld)ac.getBean("hw");
        hw1.sayHello();
你这个方法我有思考过,是不是一个接口,对应多个service?然后一个存储过程写成一个service实体类?这么写的话我得写400个service实现类
Cathy313 2017-11-03
  • 打赏
  • 举报
回复
引用 14 楼 l359122505 的回复:
[quote=引用 7 楼 rhy31328 的回复:] Class Obj = Class.forName("com.*.*.service.impl.RukuServiceImpl"); Method m = Obj.getMethod(methodName,InBusiness.class,ErrorPara.class); List li = (List) m.invoke(RukuService, bi, errorPara); 我的想法是用的用反射调方法,名字可以写个方法动态调用,但是List li = (List) m.invoke(RukuService, bi, errorPara);里面的RukuService是个注入的变量,我应该怎么处理,请求大神支援!有其他的思路可以解决的话也好。
反射这种做法想法倒是可以,但是会破坏Service的单例。[/quote] 我现在只能想到这么一个解决的方法,还有各种毛病,400个存储过程,我也很无奈,还不能根据前端的业务直接处理。我也期待有更好的方法解决。
Cathy313 2017-11-03
  • 打赏
  • 举报
回复
引用 12 楼 l359122505 的回复:
[quote=引用 9 楼 rhy31328 的回复:] [quote=引用 8 楼 l359122505 的回复:] 感觉反射避免不了你的顾虑吧,你的实际顾虑是一大堆if else的判断?
我们有一张表,里面有与code对应的存储过程名,所以把所有service的方法名都是按照存储过程名字取得,即使如此,还是要判断调哪个类,但这个可以在表中加一个字段根据业务上的分类来解决。只有注入这个变量真的是苦恼。[/quote] 一个存储过程名对应一个code记录,问题是有的service可能包含好几个转换的存储过程业务方法,这样反射就不好调用了是吧。是不是改造一下数据表,加入一个字段-类名?[/quote] 嗯嗯,我是这么想的,code,方法名,类名这样一个表
繁华终归落尽 2017-11-03
  • 打赏
  • 举报
回复
引用 7 楼 rhy31328 的回复:
Class Obj = Class.forName("com.*.*.service.impl.RukuServiceImpl"); Method m = Obj.getMethod(methodName,InBusiness.class,ErrorPara.class); List li = (List) m.invoke(RukuService, bi, errorPara); 我的想法是用的用反射调方法,名字可以写个方法动态调用,但是List li = (List) m.invoke(RukuService, bi, errorPara);里面的RukuService是个注入的变量,我应该怎么处理,请求大神支援!有其他的思路可以解决的话也好。
反射这种做法想法倒是可以,但是会破坏Service的单例。
独家de记忆 2017-11-03
  • 打赏
  • 举报
回复
1.定义一个接口; 2.20个service作为20个实现类 3.数据库存储过程名换成service实现类的名称; 4.controllor中根据条件获取到service的实现类名,使用spring的ApplicationContext 获取到实现类的实例; 以下只是简单的例子,具体根据你的业务设计

        //通过Spring的方式调用方法
        //构建容器   构建容器的时候就调用了set方法
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");//第1行
        //从容器中获取javaBean的实例   控制反转IOC
        HelloWorld hw1 = (HelloWorld)ac.getBean("hw");
        hw1.sayHello();
繁华终归落尽 2017-11-03
  • 打赏
  • 举报
回复
引用 9 楼 rhy31328 的回复:
[quote=引用 8 楼 l359122505 的回复:] 感觉反射避免不了你的顾虑吧,你的实际顾虑是一大堆if else的判断?
我们有一张表,里面有与code对应的存储过程名,所以把所有service的方法名都是按照存储过程名字取得,即使如此,还是要判断调哪个类,但这个可以在表中加一个字段根据业务上的分类来解决。只有注入这个变量真的是苦恼。[/quote] 一个存储过程名对应一个code记录,问题是有的service可能包含好几个转换的存储过程业务方法,这样反射就不好调用了是吧。是不是改造一下数据表,加入一个字段-类名?
Cathy313 2017-11-03
  • 打赏
  • 举报
回复
引用 10 楼 chris9421xy 的回复:
为什么不把存储过程的代码写到一个实现类里面,然后在service里调用方法。方法分类。
我就是把存储过程的代码都写到service实现类了,总不能service调service吧?
半城煙沙 2017-11-03
  • 打赏
  • 举报
回复
为什么不把存储过程的代码写到一个实现类里面,然后在service里调用方法。方法分类。
Cathy313 2017-11-03
  • 打赏
  • 举报
回复
引用 8 楼 l359122505 的回复:
感觉反射避免不了你的顾虑吧,你的实际顾虑是一大堆if else的判断?
我们有一张表,里面有与code对应的存储过程名,所以把所有service的方法名都是按照存储过程名字取得,即使如此,还是要判断调哪个类,但这个可以在表中加一个字段根据业务上的分类来解决。只有注入这个变量真的是苦恼。
繁华终归落尽 2017-11-03
  • 打赏
  • 举报
回复
感觉反射避免不了你的顾虑吧,你的实际顾虑是一大堆if else的判断?
Cathy313 2017-11-03
  • 打赏
  • 举报
回复
Class Obj = Class.forName("com.*.*.service.impl.RukuServiceImpl"); Method m = Obj.getMethod(methodName,InBusiness.class,ErrorPara.class); List li = (List) m.invoke(RukuService, bi, errorPara); 我的想法是用的用反射调方法,名字可以写个方法动态调用,但是List li = (List) m.invoke(RukuService, bi, errorPara);里面的RukuService是个注入的变量,我应该怎么处理,请求大神支援!有其他的思路可以解决的话也好。
Cathy313 2017-11-03
  • 打赏
  • 举报
回复
引用 4 楼 l359122505 的回复:
我在想控制器调用20多个Service,事务回滚怎么办
是动态调用,实际上一次请求只调用一个service实现类里面的一个方法,所以事务回滚的问题好处理,他们之间互不影响
Cathy313 2017-11-03
  • 打赏
  • 举报
回复
引用 3 楼 qq_39912309 的回复:
引用 2 楼 rhy31328 的回复:
20多个都自动注入?就算都自动注入,不可能写20多个方法来调service层呀。我现在的关键问题是怎么自动调用不同的service类,而不是spring注入
什么叫自动调用不同的service类?非得一个controller调用所有的service?
因为我们的项目是从调取存储过程转化过来的,存储过程好搞,只要知道输入参数和输出参数类型直接根据存储过程对应的code调用就可以了。所以之前只用到一个controller。现在把存储过程全改成java的service实现类来实现了,那就得调service层里面的方法了,调用过程大致相同,但不可能写20个除了调用类名和方法不同其他完全一样的controller吧?
繁华终归落尽 2017-11-03
  • 打赏
  • 举报
回复
我在想控制器调用20多个Service,事务回滚怎么办
qq_39912309 2017-11-03
  • 打赏
  • 举报
回复
引用 2 楼 rhy31328 的回复:
20多个都自动注入?就算都自动注入,不可能写20多个方法来调service层呀。我现在的关键问题是怎么自动调用不同的service类,而不是spring注入
什么叫自动调用不同的service类?非得一个controller调用所有的service?
Cathy313 2017-11-03
  • 打赏
  • 举报
回复
20多个都自动注入?就算都自动注入,不可能写20多个方法来调service层呀。我现在的关键问题是怎么自动调用不同的service类,而不是spring注入
独家de记忆 2017-11-03
  • 打赏
  • 举报
回复
引用 19 楼 r562253897 的回复:
[quote=引用 17 楼 rhy31328 的回复:] [quote=引用 13 楼 r562253897 的回复:] 1.定义一个接口; 2.20个service作为20个实现类 3.数据库存储过程名换成service实现类的名称; 4.controllor中根据条件获取到service的实现类名,使用spring的ApplicationContext 获取到实现类的实例; 以下只是简单的例子,具体根据你的业务设计

        //通过Spring的方式调用方法
        //构建容器   构建容器的时候就调用了set方法
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");//第1行
        //从容器中获取javaBean的实例   控制反转IOC
        HelloWorld hw1 = (HelloWorld)ac.getBean("hw");
        hw1.sayHello();
你这个方法我有思考过,是不是一个接口,对应多个service?然后一个存储过程写成一个service实体类?这么写的话我得写400个service实现类[/quote] 你是20个service里面,每个实例有很多方法是吧,那你现在的存储过程和方法应该是一对一的吧? 只是不想破坏service的单例,可以在实例上使用spring的实例,method使用反射; 也就是你需要在每个存储过程的位置配置实例名和方法名,才能对应起来。[/quote] 还有一点,你20多个实例都有了,每个里面又20来个方法,那创建400个实例又有什么问题呢。。。。
独家de记忆 2017-11-03
  • 打赏
  • 举报
回复
引用 17 楼 rhy31328 的回复:
[quote=引用 13 楼 r562253897 的回复:] 1.定义一个接口; 2.20个service作为20个实现类 3.数据库存储过程名换成service实现类的名称; 4.controllor中根据条件获取到service的实现类名,使用spring的ApplicationContext 获取到实现类的实例; 以下只是简单的例子,具体根据你的业务设计

        //通过Spring的方式调用方法
        //构建容器   构建容器的时候就调用了set方法
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");//第1行
        //从容器中获取javaBean的实例   控制反转IOC
        HelloWorld hw1 = (HelloWorld)ac.getBean("hw");
        hw1.sayHello();
你这个方法我有思考过,是不是一个接口,对应多个service?然后一个存储过程写成一个service实体类?这么写的话我得写400个service实现类[/quote] 你是20个service里面,每个实例有很多方法是吧,那你现在的存储过程和方法应该是一对一的吧? 只是不想破坏service的单例,可以在实例上使用spring的实例,method使用反射; 也就是你需要在每个存储过程的位置配置实例名和方法名,才能对应起来。
繁华终归落尽 2017-11-03
  • 打赏
  • 举报
回复
引用 16 楼 rhy31328 的回复:
[quote=引用 14 楼 l359122505 的回复:] [quote=引用 7 楼 rhy31328 的回复:] Class Obj = Class.forName("com.*.*.service.impl.RukuServiceImpl"); Method m = Obj.getMethod(methodName,InBusiness.class,ErrorPara.class); List li = (List) m.invoke(RukuService, bi, errorPara); 我的想法是用的用反射调方法,名字可以写个方法动态调用,但是List li = (List) m.invoke(RukuService, bi, errorPara);里面的RukuService是个注入的变量,我应该怎么处理,请求大神支援!有其他的思路可以解决的话也好。
反射这种做法想法倒是可以,但是会破坏Service的单例。[/quote] 我现在只能想到这么一个解决的方法,还有各种毛病,400个存储过程,我也很无奈,还不能根据前端的业务直接处理。我也期待有更好的方法解决。[/quote] 可以考虑从设计模式的角度来优化,比如策略
加载更多回复(1)

81,092

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧