在java中由类名和方法名字符串实现其调用方式

 更新时间:2020年09月24日 11:04:30   作者:龙昊雪  
这篇文章主要介绍了在java中由类名和方法名字符串实现其调用方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

js里通过eval()函数,在知道某个方法名是可以实现调用该方法,那么在java里边又怎么实现的呢?

java里边是通过反射机制来实现,代码如下:

import java.lang.reflect.Method;
 
public class Test {
 public static void main(String[] args) throws Exception {
 String className = "com.runqianapp.ngr.alias.example.FunClass";
 String methodName = "sayHello";
 Class clz = Class.forName(className);
 // 
 Object obj = clz.newInstance();
 //获取方法 
 Method m = obj.getClass().getDeclaredMethod(methodName, String.class);
 //调用方法 
 String result = (String) m.invoke(obj, "aaaaa");
 System.out.println(result);
 }
}
 
class FunClass{
 public String sayHello(String s){
 System.out.println(s);
 return "hello!";
 }
}

补充知识:一个controller调用根据不同业务分发不同service

在一个项目中需要写很多的controller去调用不同的service,而写一个网关可以省去写controller层的痛苦。

下面开始介绍可以分发不同service。

1.因为service在项目启动时就已全部注入到spring容器中,所以我们需要写一个工具类,可以从spring上下文(applicationContext)中获取到对应service

@Component
public class SpringUtil implements ApplicationContextAware {
 
 @Autowired
 private static ApplicationContext applicationContext;
 
 @Override
 public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
  if (SpringUtil.applicationContext == null) {
   SpringUtil.applicationContext = applicationContext;
  }
  System.out.println("========ApplicationContext配置成功,在普通类可以通过调用SpringUtil.getAppContext()获取applicationContext对象,applicationContext=" + SpringUtil.applicationContext + "========");
 }
 
 //获取applicationContext
 public static ApplicationContext getApplicationContext() {
  return applicationContext;
 }
 
 //通过name获取 Bean.
 public static Object getBean(String name) {
  return getApplicationContext().getBean(name);
 }
 
 //通过class获取Bean.
 public static <T> T getBean(Class<T> clazz) {
  return getApplicationContext().getBean(clazz);
 }
 
 //通过name,以及Clazz返回指定的Bean
 public static <T> T getBean(String name, Class<T> clazz) {
  return getApplicationContext().getBean(name, clazz);
 }
}

2.上面的SpringUtil我们已经可以在上下文中直接取到对于的service了,下面就开始编写controller进行请求的分发(我称之为网关)。首先我们需要先写一个抽象类,来定义service,这样接下来的sevice只需要继承这个抽象类即可(我们还可以写一些时间统计,交易流水入库等。。自我感觉很大的用处)。

public abstract class RootService { 
 private Logger logger = LoggerFactory.getLogger(RootService.class); 
 private long beforeTime; 
 private long endTime; 
 
 private void before (String action) {
  beforeTime = System.currentTimeMillis();
  logger.info("交易:" + action + "开始时间:" + beforeTime);
 }
 
 private void end (String action) {
  endTime = System.currentTimeMillis();
  long time = endTime - beforeTime;
  logger.info("交易:" + action + "结束时间:" + endTime);
  logger.info("交易:" + action + "耗时:" + time);
 }
 
 public JSONObject execute(String actionName,Map map) {
  before(actionName);
  JSONObject jsonObject = doNext(map);
  end(actionName);
  return jsonObject;
 }
 
 private JSONObject doNext(Map map) {
  try {
   return doAction(map);
  } catch (Exception e) {
   e.printStackTrace();
   JSONObject js = new JSONObject();
   js.put("retCode","000000");
   js.put("retMsg","程序报错");
   return js;
  }
 } 
 protected abstract JSONObject doAction(Map map); 
}

3.一切准备就绪,我们可以开始编写contrconoller了(网关)

@Controller
@RequestMapping("/root")
public class RootController {
 
 @ResponseBody
 @RequestMapping(value = "/h5.do",produces = {"application/json;charset=UTF-8"},method = RequestMethod.POST)
 public JSONObject root(@RequestBody Map<String,Object> map, HttpServletRequest httpServletRequest){
  String service = (String) map.get("service");
 
  JSONObject js = new JSONObject();
  RootService rootService = (RootService) SpringUtil.getBean(service);
 
  return rootService.execute(service,map);
 } 
}

到这里一个网关就写好了,然后我们写一个service进行测试一下(对应的Dao层我就不现丑了,相信大家都会)

@Service
public class UserServiceImpl extends RootService{
 private Logger logger = LoggerFactory.getLogger(UserService.class);
 
 @Autowired
 private UserDao userDao;
 
 @Override
 protected JSONObject doAction(Map map) {
  JSONObject js = new JSONObject();
  String id = (String) map.get("id");
  User user = userDao.getUser(id);
  js.put("user",user);
  logger.info("进入了UserService");
  return js;
 }
}

下面我们用postman测试一下测试报文为:

{
 "id":"1",
 "service":"userServiceImpl"
}

控制台打印为:

2019-10-18 17:24:41.089 INFO 6452 --- [nio-8080-exec-2] c.s.s.service.util.RootService : 交易:userService开始时间:1571390681089
2019-10-18 17:24:41.138 INFO 6452 --- [nio-8080-exec-2] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2019-10-18 17:24:41.227 INFO 6452 --- [nio-8080-exec-2] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2019-10-18 17:24:41.255 INFO 6452 --- [nio-8080-exec-2] c.s.s.service.impl.UserService : 进入了UserService
2019-10-18 17:24:41.256 INFO 6452 --- [nio-8080-exec-2] c.s.s.service.util.RootService : 交易:userService结束时间:1571390681256
2019-10-18 17:24:41.256 INFO 6452 --- [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中由类名和方法名字符串实现其调用方式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 运用springboot搭建并部署web项目的示例

    运用springboot搭建并部署web项目的示例

    这篇文章主要介绍了运用springboot搭建并部署web项目的示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • Java多线程中的ThreadLocal应用场景及问题解读

    Java多线程中的ThreadLocal应用场景及问题解读

    这篇文章主要介绍了Java多线程中的ThreadLocal应用场景及问题解读,ThreadLocal这个类在多线程并发中主要的使用场景是什么呢,我们都知道多线程并发问题实际就是多个线程对公共资源访问和修改问题,需要的朋友可以参考下
    2023-12-12
  • Java中JDBC实现动态查询的实例详解

    Java中JDBC实现动态查询的实例详解

    从多个查询条件中随机选择若干个组合成一个DQL语句进行查询,这一过程叫做动态查询。下面通过实例代码给大家讲解JDBC实现动态查询的方法,需要的朋友参考下吧
    2017-07-07
  • Java使用递归法解决汉诺塔问题的代码示例

    Java使用递归法解决汉诺塔问题的代码示例

    这篇文章主要介绍了Java使用递归法解决汉诺塔问题的代码示例,汉诺塔问题是使用递归解决问题的经典范例,用到的算法非常简单,需要的朋友可以参考下
    2016-04-04
  • SpringBoot异常处理器的使用与添加员工功能实现流程介绍

    SpringBoot异常处理器的使用与添加员工功能实现流程介绍

    设计完了登录与退出功能还只完成了冰山一角,经过测试发现,我们以url的方式来访问网站时可以直接跳过登陆页面进入后台页面,这样显然是不合理的,下面我们通过异常拦截器+boot来做到访问限制,以及实现新增员工功能,制作全局异常处理器
    2022-10-10
  • springcloud下hibernate本地化方言配置方式

    springcloud下hibernate本地化方言配置方式

    这篇文章主要介绍了springcloud下hibernate本地化方言配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • 一起来学习Java IO的转化流

    一起来学习Java IO的转化流

    这篇文章主要为大家详细介绍了Java IO的转化流,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • 详解Java线程池如何实现优雅退出

    详解Java线程池如何实现优雅退出

    这篇文章我们将从源码角度深度解析线程池是如何优雅的退出程序的,文中的示例代码讲解详细,对我们学习java线程池有一定帮助,需要的可以参考一下
    2022-07-07
  • java实现多线程的两种方式继承Thread类和实现Runnable接口的方法

    java实现多线程的两种方式继承Thread类和实现Runnable接口的方法

    下面小编就为大家带来一篇java实现多线程的两种方式继承Thread类和实现Runnable接口的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-09-09
  • Java实现将PDF转为图片格式的方法详解

    Java实现将PDF转为图片格式的方法详解

    PDF文件和图片文件,这是两种完全不一样的格式,可是有的时候这两种格式却是有相互转换的需要,本文将介绍如何通过Java应用程序快速高效地将PDF转为图片格式。一起来看看吧
    2023-03-03

最新评论