Play 2.6 Action组合

英文原文地址
https://playframework.com/documentation/2.6.x/JavaActionsComposition

Action composition

action是一个返回play.mvc.Result对象的方法。实际上play在内部将actions当作functions管理(Actually, Play manages internally actions as functions),在Java API中action为一个play.mvc.action实例。Play创建了一个root action保证我们能够调到合适的action方法,这也允许我们进行action的组合。

Composing actions
public class VerboseAction extends play.mvc.Action.Simple {
    public CompletionStage<Result> call(Http.Context ctx) {
        Logger.info("Calling action for {}", ctx);
        return delegate.call(ctx);
    }
}

可以通过@With注解将该action与其他acion组合起来

//controller中的方法都为一个action,controller可以视为action的集合
@With(VerboseAction.class)
public Result verboseIndex() {
    return ok("It works!");
}

如果需要代理到被封装的action,可以使用delegate.call(...)(At one point you need to delegate to the wrapped action using delegate.call(...)

也可以通过自定义的注解来混合多个action

@Security.Authenticated
@Cached(key = "index.result")
public Result authenticatedCachedIndex() {
    return ok("It works!");
}

注意:
- 每个请求都要由不同的play.mvc.Action实例来处理。如果使用单例模式在复杂情况下可能会出错。如果使用Spring作为DI容器,要将action设置为prototype
- play.mvc.Security.Authenticatedplay.cache.Cached 都是Play预定义的注解和Action类

在controller上进行注解
@Security.Authenticated
public class Admin extends Controller {
...

}

这中情况下contorller中所有的action方法会和Security.Authenticated混合

将action中的对象传递给controller
public class PassArgAction extends play.mvc.Action.Simple {
    public CompletionStage<Result> call(Http.Context ctx) {
        ctx.args.put("user", User.findById(1234));
        return delegate.call(ctx);
    }
}

@With(PassArgAction.class)
public static Result passArgIndex() {
    Object user = ctx().args.get("user");
    return ok(Json.toJson(user));
}
查看action调用顺序

在logback.xml中加入以下信息

<logger name="play.mvc.Action" level="DEBUG" />

可以在日志信息中看到以下结果

[debug] play.mvc.Action - ### Start of action order
[debug] play.mvc.Action - 1. ...
[debug] play.mvc.Action - 2. ...
[debug] play.mvc.Action - ### End of action order
使用依赖注入

在组合acion时,可以使用运行时依赖注入编译期依赖注入

运行时

通过一个缓存的例子来说明,首先定义一个注解

@With(MyOwnCachedAction.class)
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface WithCache {
    String key();
}

然后通过依赖注入的方式定义action

public class MyOwnCachedAction extends Action<WithCache> {

    private final AsyncCacheApi cacheApi;

    @Inject
    public MyOwnCachedAction(AsyncCacheApi cacheApi) {
        this.cacheApi = cacheApi;
    }

    @Override
    public CompletionStage<Result> call(Http.Context ctx) {
        return cacheApi.getOrElseUpdate(configuration.key(), () -> delegate.call(ctx));
    }
}
编译期依赖注入

需要覆盖BuiltInComponentsjavaHandlerComponents方法,将自己的action添加到JavaHandlerComponents

public class MyComponents extends BuiltInComponentsFromContext
        implements NoHttpFiltersComponents, EhCacheComponents {

    public MyComponents(ApplicationLoader.Context context) {
        super(context);
    }

    @Override
    public Router router() {
        return Router.empty();
    }

    @Override
    public MappedJavaHandlerComponents javaHandlerComponents() {
        return super.javaHandlerComponents()
                // Add action that does not depends on any other component
                .addAction(VerboseAction.class, VerboseAction::new)
                // Add action that depends on the cache api
                .addAction(MyOwnCachedAction.class, () -> new MyOwnCachedAction(defaultCacheApi()));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值