在java中由类名和⽅法名字符串实现其调⽤⽅式
js⾥通过eval()函数,在知道某个⽅法名是可以实现调⽤该⽅法,那么在java⾥边⼜怎么实现的呢?
java⾥边是通过反射机制来实现,代码如下:
import flect.Method;
public class Test {
public static void main(String[] args) throws Exception {
String className = "ample.FunClass";
String methodName = "sayHello";
Class clz = Class.forName(className);
//
Object obj = wInstance();
/
/获取⽅法
Method m = Class().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配置成功,在普通类可以通过调⽤AppContext()获取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 = Logger(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) ("service");
JSONObject js = new JSONObject();
RootService rootService = (RootService) Bean(service);
ute(service,map);
}
}
到这⾥⼀个⽹关就写好了,然后我们写⼀个service进⾏测试⼀下(对应的Dao层我就不现丑了,相信⼤家都会)
@Service
public class UserServiceImpl extends RootService{
private Logger logger = Logger(UserService.class);
@Autowired
private UserDao userDao;
@Override
protected JSONObject doAction(Map map) {
JSONObject js = new JSONObject();
js调用方法的三种写法
String id = (String) ("id");
User user = User(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 -
2019-10-18 17:24:41.227 INFO 6452 --- [nio-8080-exec-2] com.zaxxer.hikari.HikariDataSource : Hikari
Pool-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中由类名和⽅法名字符串实现其调⽤⽅式就是⼩编分享给⼤家的全部内容了,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。