在java中由类名和方法名字符串实现其调用方式
js里通过eval()函数,在知道某个方法名是可以实现调用该方法,那么在java里边又怎么实现的呢?
java里边是通过反射机制来实现,代码如下:
importjava.lang.reflect.Method; publicclassTest{ publicstaticvoidmain(String[]args)throwsException{ StringclassName="com.runqianapp.ngr.alias.example.FunClass"; StringmethodName="sayHello"; Classclz=Class.forName(className); // Objectobj=clz.newInstance(); //获取方法 Methodm=obj.getClass().getDeclaredMethod(methodName,String.class); //调用方法 Stringresult=(String)m.invoke(obj,"aaaaa"); System.out.println(result); } } classFunClass{ publicStringsayHello(Strings){ System.out.println(s); return"hello!"; } }
补充知识:一个controller调用根据不同业务分发不同service
在一个项目中需要写很多的controller去调用不同的service,而写一个网关可以省去写controller层的痛苦。
下面开始介绍可以分发不同service。
1.因为service在项目启动时就已全部注入到spring容器中,所以我们需要写一个工具类,可以从spring上下文(applicationContext)中获取到对应service
@Component publicclassSpringUtilimplementsApplicationContextAware{ @Autowired privatestaticApplicationContextapplicationContext; @Override publicvoidsetApplicationContext(ApplicationContextapplicationContext)throwsBeansException{ if(SpringUtil.applicationContext==null){ SpringUtil.applicationContext=applicationContext; } System.out.println("========ApplicationContext配置成功,在普通类可以通过调用SpringUtil.getAppContext()获取applicationContext对象,applicationContext="+SpringUtil.applicationContext+"========"); } //获取applicationContext publicstaticApplicationContextgetApplicationContext(){ returnapplicationContext; } //通过name获取Bean. publicstaticObjectgetBean(Stringname){ returngetApplicationContext().getBean(name); } //通过class获取Bean. publicstaticTgetBean(Class clazz){ returngetApplicationContext().getBean(clazz); } //通过name,以及Clazz返回指定的Bean publicstatic TgetBean(Stringname,Class clazz){ returngetApplicationContext().getBean(name,clazz); } }
2.上面的SpringUtil我们已经可以在上下文中直接取到对于的service了,下面就开始编写controller进行请求的分发(我称之为网关)。首先我们需要先写一个抽象类,来定义service,这样接下来的sevice只需要继承这个抽象类即可(我们还可以写一些时间统计,交易流水入库等。。自我感觉很大的用处)。
publicabstractclassRootService{ privateLoggerlogger=LoggerFactory.getLogger(RootService.class); privatelongbeforeTime; privatelongendTime; privatevoidbefore(Stringaction){ beforeTime=System.currentTimeMillis(); logger.info("交易:"+action+"开始时间:"+beforeTime); } privatevoidend(Stringaction){ endTime=System.currentTimeMillis(); longtime=endTime-beforeTime; logger.info("交易:"+action+"结束时间:"+endTime); logger.info("交易:"+action+"耗时:"+time); } publicJSONObjectexecute(StringactionName,Mapmap){ before(actionName); JSONObjectjsonObject=doNext(map); end(actionName); returnjsonObject; } privateJSONObjectdoNext(Mapmap){ try{ returndoAction(map); }catch(Exceptione){ e.printStackTrace(); JSONObjectjs=newJSONObject(); js.put("retCode","000000"); js.put("retMsg","程序报错"); returnjs; } } protectedabstractJSONObjectdoAction(Mapmap); }
3.一切准备就绪,我们可以开始编写contrconoller了(网关)
@Controller @RequestMapping("/root") publicclassRootController{ @ResponseBody @RequestMapping(value="/h5.do",produces={"application/json;charset=UTF-8"},method=RequestMethod.POST) publicJSONObjectroot(@RequestBodyMapmap,HttpServletRequesthttpServletRequest){ Stringservice=(String)map.get("service"); JSONObjectjs=newJSONObject(); RootServicerootService=(RootService)SpringUtil.getBean(service); returnrootService.execute(service,map); } }
到这里一个网关就写好了,然后我们写一个service进行测试一下(对应的Dao层我就不现丑了,相信大家都会)
@Service publicclassUserServiceImplextendsRootService{ privateLoggerlogger=LoggerFactory.getLogger(UserService.class); @Autowired privateUserDaouserDao; @Override protectedJSONObjectdoAction(Mapmap){ JSONObjectjs=newJSONObject(); Stringid=(String)map.get("id"); Useruser=userDao.getUser(id); js.put("user",user); logger.info("进入了UserService"); returnjs; } }
下面我们用postman测试一下测试报文为:
{ "id":"1", "service":"userServiceImpl" }
控制台打印为:
2019-10-1817:24:41.089INFO6452---[nio-8080-exec-2]c.s.s.service.util.RootService:交易:userService开始时间:1571390681089
2019-10-1817:24:41.138INFO6452---[nio-8080-exec-2]com.zaxxer.hikari.HikariDataSource:HikariPool-1-Starting...
2019-10-1817:24:41.227INFO6452---[nio-8080-exec-2]com.zaxxer.hikari.HikariDataSource:HikariPool-1-Startcompleted.
2019-10-1817:24:41.255INFO6452---[nio-8080-exec-2]c.s.s.service.impl.UserService:进入了UserService
2019-10-1817:24:41.256INFO6452---[nio-8080-exec-2]c.s.s.service.util.RootService:交易:userService结束时间:1571390681256
2019-10-1817:24:41.256INFO6452---[nio-8080-exec-2]c.s.s.service.util.RootService:交易:userService耗时:167
返回为:
{ "user":{ "user_id":"1", "password":"123456", "user_name":"张三" } }
总结:这样写法的好处在于1.有一个统一的入口,不需要在编写controller,可以专注于业务(service)2.可以在公共入口做公共处理。
以上这篇在java中由类名和方法名字符串实现其调用方式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。