java 分发器_在Java中用反射来做控制器分发

项目用的是 netty,需要再handler里面去处理请求.请过过来之后,原先的做法是直接做if else判断,但是每次加一个api,我就需要改一次常量定义和 handler,感觉太麻烦了.

我想的就是能不能用我们在php里的常用方法(用数组做api和controller的映射).尝试了下如下做法:

1.有一个hashMap里面存的就是一个 api => className.methodName.

2.然后在handler里接受到api的请求之后,获取该api对应的值.例如现在的请求api为user.get,然后以user.get为 key,找到其值为UserService.getInfo,然后再通过.分隔,再通过反射把请求的参数也带上.

这样就达到了控制器分发的效果.实际压测发现效率不降反升,我猜可能是因为用if else判断的时候要每个都判断一次,如果100个控制器,而现在需要找的又正好是最后一个控制器,那么就需要做100次判断.如果用hashMap就一次定位找到,所以速度反而快了?

先上之前的老代码:// handler code

Map objectMap = new HashMap();

//user.get

if(method.equals(Constants.MethodUserInfo)){

objectMap = UserService.getInfo(httpParams);

}

//misc.getVersion

if(method.equals(Constants.MethodMiscGetVersion)){

objectMap = MiscService.getVersion(httpParams);

}

//feed.getType

if(method.equals(Constants.MethodFeedGetType)){

objectMap = FeedService.getType(httpParams);

}

//msg.get

if(method.equals(Constants.MethodMsgGet)){

objectMap = MessageService.list(httpParams);

}

//feed.get

if(method.equals(Constants.MethodGetFeed)){

objectMap = FeedService.list(httpParams);

}

//uploadToken.get

if(method.equals(Constants.MethodUploadToken)){

objectMap = UploadService.uploadToken(httpParams);

}

//feed.add

if(method.equals(Constants.MethodFeedAdd)){

objectMap = FeedService.post(httpParams);

}

//sendWeChat

if(method.equals(Constants.MethodSendWeChat)){

objectMap = MessageService.sendWeChatToSomebody(httpParams);

}

//comment.add

if(method.equals(Constants.MethodComment)){

objectMap = CommentService.add(httpParams);

}

//fav.add

if(method.equals(Constants.MethodFavAdd)){

objectMap = FavService.add(httpParams);

}

//fav.del

if(method.equals(Constants.MethodFavDel)){

objectMap = FavService.del(httpParams);

}

//editInfo

if(method.equals(Constants.MethodEditUserInfo)){

objectMap = UserService.edit(httpParams);

}

//interest.add

if(method.equals(Constants.MethodInterestAdd)){

objectMap = TagService.add(httpParams);

}

//interest.del

if(method.equals(Constants.MethodInterestDel)){

objectMap = TagService.del(httpParams);

}

//register

if(method.equals(Constants.MethodRegister)){

objectMap = LoginService.register(httpParams);

}

//login

if(method.equals(Constants.MethodLogin)){

objectMap = LoginService.login(httpParams);

}

//logout

if(method.equals(Constants.MethodLogout)){

objectMap = LoginService.logout(httpParams);

}

JSONObject jsonObject = new JSONObject(objectMap);

json = jsonObject.toString();public class Constants {

public final static String MethodBase = "http://localhost:5000/?method=";

public final static String MethodUserInfo = "user.get";

public final static String MethodEditUserInfo = "editInfo";

public final static String MethodMiscGetVersion = "misc.getVersion";

public final static String MethodFeedGetType = "feed.getType";

public final static String MethodGetFeed = "feed.get";

public final static String MethodFeedAdd = "feed.add";

public final static String MethodMsgGet = "msgs.get";

public final static String MethodSendWeChat = "sendWechat";

public final static String MethodUploadToken = "uploadToken.get";

public final static String MethodComment = "comment.add";

public final static String MethodFavAdd = "fav.add";

public final static String MethodFavDel = "fav.del";

public final static String MethodInterestAdd = "interest.add";

public final static String MethodInterestDel = "interest.del";

public final static String MethodRegister = "register";

public final static String MethodLogin = "login";

public final static String MethodLogout = "logout";

}

因为习惯了在php的入口里做控制器分发,所以想java里面肯定能实现.吃饭的时候问下领导,领导说可以用反射,但是一般都是远程调用才去那么做,就像上面那样写if else就行了,没多少.

不管怎么说最后我还是改了.性能还不知道,先用着,反射的内容也没深入学习,等项目完了,再来复习.if(Constants.methodMap.containsKey(method)){

String classAndMethod = Constants.methodMap.get(method);

String[] classAndMethodArray = classAndMethod.split("\\.");

Class> className = null;

try {

className = Class.forName("me.topit.site.service."+classAndMethodArray[0]);

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

Method methodName = null;

try {

methodName = className.getMethod(classAndMethodArray[1],HttpParams.class);

} catch (NoSuchMethodException e) {

e.printStackTrace();

}

try {

Map objectMap = (Map) methodName.invoke(null,httpParams);

JSONObject jsonObject = new JSONObject(objectMap);

json = jsonObject.toString();

} catch (InvocationTargetException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

}

}else{

Map errorMsg = BaseService.error("该API不存在.");

JSONObject jsonObject = new JSONObject(errorMsg);

json = jsonObject.toString();

}

常量的定义我也换了:public class Constants {

public final static String MethodBase = "http://localhost:5000/?method=";

public final static HashMap methodMap = new HashMap(){{

// 系统类

put("misc.getVersion", "MiscService.getVersion");

// 用户类

put("user.get", "UserService.getInfo");

put("editInfo", "UserService.edit");

// feed类

put("feed.getType", "FeedService.getType");

put("feed.get", "FeedService.list");

put("feed.add", "FeedService.post");

// 消息类

put("msgs.get", "MessageService.list");

put("sendWechat", "MessageService.sendWeChatToSomebody");

// 上传类

put("uploadToken.get", "UploadService.uploadToken");

// 评论类

put("comment.add",  "CommentService.add");

// 点赞类

put("fav.add", "FavService.add");

put("fav.del", "FavService.del");

// 兴趣标签类

put("interest.add", "TagService.add");

put("interest.del", "TagService.del");

// 注册类

put("register", "LoginService.register");

put("login", "LoginService.login");

put("logout", "LoginService.logout");

}};

}

我测试判断,发现除了第一次之外,之后的请求中都是修改为反射后的效率更高,没有看出效率受到影响.ab -c10 -n1000 http://localhost:5000/?method=user.get&id=1

Concurrency Level:      10

Time taken for tests:   1.278 seconds

Complete requests:      1000

Failed requests:        0

Total transferred:      81000 bytes

HTML transferred:       42000 bytes

// 没有用反射的情况,每秒可以处理1645.70个请求

Requests per second:    782.23 [#/sec] (mean)

Time per request:       12.784 [ms] (mean)

Requests per second:    1287.48 [#/sec] (mean)

Time per request:       7.767 [ms] (mean)

Requests per second:    1667.01 [#/sec] (mean)

Time per request:       5.999 [ms] (mean)

Requests per second:    1797.64 [#/sec] (mean)

Time per request:       5.563 [ms] (mean)

Requests per second:    2136.11 [#/sec] (mean)

Time per request:       4.681 [ms] (mean)

Requests per second:    1769.91 [#/sec] (mean)

Time per request:       5.650 [ms] (mean)

Requests per second:    2079.54 [#/sec] (mean)

Time per request:       4.809 [ms] (mean)

// 使用用反射的情况,每秒可以处理 1771.13 个请求

Requests per second:    728.11 [#/sec] (mean)

Time per request:       13.734 [ms] (mean)

Requests per second:    1318.63 [#/sec] (mean)

Time per request:       7.584 [ms] (mean)

Requests per second:    1833.21 [#/sec] (mean)

Time per request:       5.455 [ms] (mean)

Requests per second:    1818.62 [#/sec] (mean)

Time per request:       5.499 [ms] (mean)

Requests per second:    2075.64 [#/sec] (mean)

Time per request:       4.818 [ms] (mean)

Requests per second:    2238.91 [#/sec] (mean)

Time per request:       4.466 [ms] (mean)

Requests per second:    2384.78 [#/sec] (mean)

Time per request:       4.193 [ms] (mean)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值