Play! Framework学习笔记:ActionInvoker源码分析("Play! Framework深度解析:ActionInvoker源码学习笔记")
原创
一、引言
Play! Framework 是一个基于 Java/Scala 的轻量级、无状态、异步的 Web 框架。在 Play! 中,ActionInvoker 是一个非常核心的组件,它负责调用控制器中的 Action 方法,并将导致返回给客户端。本文将深入分析 Play! Framework 中 ActionInvoker 的源码,帮助读者更好地懂得其工作原理。
二、ActionInvoker 简介
ActionInvoker 是 Play! Framework 中负责调用 Action 方法的组件。它首要包含以下几个功能:
- 解析请求,找到对应的 Action 方法;
- 调用 Action 方法,并处理方法的返回值;
- 将导致返回给客户端。
三、源码分析
下面我们将从 ActionInvoker 的首要方法入手,分析其源码实现。
3.1、ActionInvoker 类结构
public class ActionInvoker {
private final Play play;
private final Router router;
private final ActionCreator actionCreator;
private final ResultEnhancer resultEnhancer;
private final HttpErrorHandler errorHandler;
private final RequestHandler requestHandler;
public ActionInvoker(Play play, Router router, ActionCreator actionCreator,
ResultEnhancer resultEnhancer, HttpErrorHandler errorHandler,
RequestHandler requestHandler) {
this.play = play;
this.router = router;
this.actionCreator = actionCreator;
this.resultEnhancer = resultEnhancer;
this.errorHandler = errorHandler;
this.requestHandler = requestHandler;
}
// ... 省略其他方法
}
3.2、handle 方法
handle 方法是 ActionInvoker 的核心方法,它负责处理请求,并调用对应的 Action 方法。
public Result handle(Http.Request request) {
try {
// 解析请求,找到对应的 Action 方法
Request request2 = wrapRequest(request);
Action action = router.getAction(request2);
if (action == null) {
return notFound("No route found for " + request2);
}
// 创建 ActionContext 对象
ActionContext context = new ActionContext(action, request2);
// 调用 Action 方法
Result result = actionCreator.create(action, context);
// 处理返回导致
return resultEnhancer.enhance(result, context);
} catch (Exception e) {
// 处理异常
return errorHandler.onServerError(request, e);
}
}
3.3、wrapRequest 方法
wrapRequest 方法负责将 Http.Request 对象包装为 Play 的 Request 对象。
private Request wrapRequest(Http.Request request) {
return new Request(request.method(), request.uri(), request.version(), request.headers(), request.body());
}
3.4、Router 类
Router 类负责路由解析,它包含一个路由表,用于查找请求对应的 Action 方法。
public class Router {
private final Map
routes = new HashMap<>(); public void addRoute(String pattern, String controller, String action, String method) {
routes.put(pattern, new Route(pattern, controller, action, method));
}
public Action getAction(Request request) {
for (Route route : routes.values()) {
if (route.matches(request)) {
return route.createAction();
}
}
return null;
}
// ... 省略其他方法
}
3.5、ActionCreator 类
ActionCreator 类负责创建 Action 对象,并调用其对应的方法。
public class ActionCreator {
public Result create(Action action, ActionContext context) {
try {
// 获取 Action 方法参数
Method method = action.getMethod();
Object[] params = action.getParams(context);
// 调用 Action 方法
return (Result) method.invoke(action.getController(), params);
} catch (Exception e) {
throw new RuntimeException("Error invoking action", e);
}
}
// ... 省略其他方法
}
四、总结
本文详细分析了 Play! Framework 中 ActionInvoker 的源码,介绍了其核心功能和工作原理。通过对 ActionInvoker 的深入懂得,我们可以更好地掌握 Play! Framework 的运行机制,为后续的优化和定制打下基础。