繁体   English   中英

在Play Framework中进行合成操作时重复相同的操作

[英]Repeating the same action when composition actions in Play Framework

我正在使用Play Framework开发服务器。 在我的几种方法中,我需要执行一些先前的操作(基本上是输入检查),因此我认为最好的方法是Action Composition

我可以毫无问题地使用几个注释

@Action1 // <---------------------------------------- This action is executed
@Action2(value = "someValue") // <------------------- This action is executed
public CompletionStage<Result> doSomething() {
    ...
}

但是,一旦我尝试重复这些操作之一,就不会执行具体操作:

@Action1 // <---------------------------------------- This action is executed
@Action2(value = "someValue") // <------------------- This action is not executed
@Action2(value = "someOtherValue") // <-------------- This action is not executed
public CompletionStage<Result> doSomething() {
    ...
}

我的Action1注释看起来像Play框架示例VerboseAnnotation ,所以我认为不值得在这里编写它。 由于可以重复执行Action2批注,因此我声明了RepeatableAction2批注,如下所示:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RepeatableAction2 {
    Action2[] value() default {};
}

Action2看起来像这样:

@With(Action2Impl.class)
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(value = RepeatableAction2.class)
public @interface Action2 {
    String value();
}

该方法已正确注释。 当我添加:

for (Method m : Application.class.getDeclaredMethods()) {
    RequiredJsonValues reqs = m.getAnnotation(RequiredJsonValues.class);
    for (RequiredJsonValue req : reqs.value()) {
        System.out.println("Method: " + m + " annotation: " + req);
    }
}

在方法开始时

Method: public java.util.concurrent.CompletionStage controllers.SomeController.doSomething() annotation: @util.Action2(value=someValue)
Method: public java.util.concurrent.CompletionStage controllers.SomeController.doSomething() annotation: @util.Action2(value=someOtherValue)

那我在做什么错? 还有其他方法可以将相同的动作以不同的值链接几次吗?

终于我使它工作了

正如这里所解释的 Java 8编译器不需要编写RepeatableAction2 ,但是它在编译时添加了它,因此我需要为该注释添加一个实现:

@With(RepeatableAction2Impl.class)
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RepeatableAction2 {
    Action2[] value() default {};
}

在实现中,我手动链接所有操作:

public class RepeatableAction2Impl extends Action<RepeatableAction2> {

    @Override
    public CompletionStage<Result> call(Http.Context ctx) {
        if (configuration.value().length > 0) {
            int actions = configuration.value().length;
            List<Action<Action2>> actionList = new ArrayList<>();
            // Create actions
            for (int i = 0; i < actions; i++) {
                Action2Impl action2Impl = new Action2Impl();
                action2Impl.configuration = configuration.value()[i];
                actionList.add(action2Impl);
            }
            // Chaining
            actionList.get(actions - 1).delegate = delegate;
            for (int i = 0; i < actions - 1; i++) {
                actionList.get(i).delegate = actionList.get(i + 1);
            }
            // Delegate the work to actions
            return actionList.get(0).call(ctx);
        } else {
            return delegate.call(ctx);
        }
    }

}

尽管这是一个可行的解决方案,但对我来说还是有点难看。 还有其他我想念的方式吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM