js里通過eval()函數,在知道某個方法名是可以實現調用該方法,那么在java里邊又怎么實現的呢?
java里邊是通過反射機制來實現,代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
@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只需要繼承這個抽象類即可(我們還可以寫一些時間統計,交易流水入庫等。。自我感覺很大的用處)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
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了(網關)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
@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層我就不現丑了,相信大家都會)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
@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測試一下測試報文為:
1
2
3
4
|
{ "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
返回為:
1
2
3
4
5
6
7
|
{ "user" : { "user_id" : "1" , "password" : "123456" , "user_name" : "張三" } } |
總結:這樣寫法的好處在于 1.有一個統一的入口,不需要在編寫controller, 可以專注于業務(service)2.可以在公共入口做公共處理。
以上這篇在java中由類名和方法名字符串實現其調用方式就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持服務器之家。
原文鏈接:https://www.cnblogs.com/chen-lhx/p/5853957.html