自定义 Java 注释以跳过方法执行 [英] Custom Java annotation to skip the method execution

查看:20
本文介绍了自定义 Java 注释以跳过方法执行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个自定义注解来跳过方法执行

这是我的注解代码,带有验证器类

@Target({ 方法,字段,参数})@Retention(RetentionPolicy.RUNTIME)@Constraint(validatedBy={MyValidator .class})公共@interface MyAnnotation {String message() 默认DEFAULT_FALSE";Class[] groups() default{};类[] payload() default{};}

我用验证器试过了.这就是我的验证器的样子

公共类 MyValidator 实现了 ConstraintValidator{@覆盖公共无效初始化(MyAnnotation arg0){}@覆盖public boolean isValid(String arg0, ConstraintValidatorContext arg1) {if(str=="msg"){返回真;}返回假;}}

这就是我想使用的方式——我想在方法级别使用注释并跳过方法执行.

我不知道是否可行..请帮忙.

公共类测试{公共静态无效主(字符串 [] args){测试 t = 新测试();布尔有效=假;有效 = t.validate();System.out.println(有效);}@MyAnnotation(message="msg")公共布尔验证(){//一些返回真或假的代码返回真;}}

解决方案

其实很简单,可以写一个最简单的方面.;-)

你的示例代码的丑陋之处在于它使用了几个你没有显示源代码的类,所以我不得不创建虚拟类/接口以使你的代码编译.你也没有展示验证器是如何应用的,所以我不得不推测.无论如何,这是一组完全自洽的示例类:

帮助类:

这只是为了让一切都可以编译的脚手架.

package de.scrum_master.app;公共接口 Payload {}

package de.scrum_master.app;公共类 ConstraintValidatorContext {}

package de.scrum_master.app;公共@interface 约束{Class[]validatedBy();}

package de.scrum_master.app;导入 java.lang.annotation.Annotation;公共接口 ConstraintValidator{无效初始化(T1注释);boolean isValid(T2 value, ConstraintValidatorContext validatorContext);}

package de.scrum_master.app;公共类 MyValidator 实现了 ConstraintValidator{@覆盖公共无效初始化(MyAnnotation 注释){}@覆盖public boolean isValid(String value, ConstraintValidatorContext validatorContext) {if ("msg".equals(value))返回真;返回假;}}

package de.scrum_master.app;导入 java.lang.annotation.Target;导入静态 java.lang.annotation.ElementType.*;导入 java.lang.annotation.Retention;导入静态 java.lang.annotation.RetentionPolicy.*;@Target({方法,字段,参数})@保留(运行时间)@Constraint(validatedBy = { MyValidator.class })公共@interface MyAnnotation {String message() 默认DEFAULT_FALSE";Class[] groups() 默认{};类[] payload() 默认{};}

驱动程序应用:

如果你想测试一些东西,你不仅需要一个正面的测试用例,还需要一个负面的测试用例.因为您没有提供,所以用户 Sampisa 的答案不是您想要的.顺便说一句,我认为您应该能够自己推断出解决方案.你甚至没有尝试.你没有任何编程经验吗?

package de.scrum_master.app;公共类应用{公共静态无效主(字符串 [] args){申请申请=新申请();System.out.println(application.validate1());System.out.println(application.validate2());}@MyAnnotation(message = "执行我")公共布尔验证1(){返回真;}@MyAnnotation(message = "msg")公共布尔验证2(){返回真;}}

方面:

除了 Sampisa 之外,我添加另一个示例方面的唯一原因是他的解决方案在他的反射使用方面不是最佳的.它很丑,而且很慢.我认为我的解决方案更优雅一些.自己看看:

package de.scrum_master.aspect;导入 org.aspectj.lang.ProceedingJoinPoint;导入 org.aspectj.lang.annotation.Around;导入 org.aspectj.lang.annotation.Aspect;@方面公共类 SkipValidationAspect {@Around("execution(@de.scrum_master.app.MyAnnotation(message=\"msg\") boolean *(..))")public boolean skipValidation(ProceedingJoinPoint thisJoinPoint) 抛出 Throwable {返回假;}}

很简单,不是吗?

控制台日志:

true错误的

等等 - 我想这就是你要找的.

I want to create a custom annotation to skip method execution

This is my annotation code, with the validator class

@Target({ METHOD , FIELD , PARAMETER } )
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy={MyValidator .class})
public @interface MyAnnotation {

    String message() default "DEFAULT_FALSE";

    Class<?>[] groups() default{};

    Class<? extends Payload>[] payload() default{};

}

I tried it with validator. This is how my validator looks like

public class MyValidator implements ConstraintValidator<MyAnnotation, String >{

    @Override
    public void initialize(MyAnnotation arg0) {

    }

    @Override
    public boolean isValid(String arg0, ConstraintValidatorContext arg1) {

        if(str=="msg"){
            return true;
        }
        return false;
    }

}

And this is how I want to use -- I want to use the annotation on method level and to skip the method execution.

I don't know if it is possible.. Please help.

public class Test {



    public static void main(String[] args) {
    Test t = new Test();
        boolean valid=false;

         valid=t.validate();
        System.out.println(valid);

    }

@MyAnnotation(message="msg")
    public boolean validate(){

     // some code to return true or false
    return true;


    }
}

解决方案

It is actually very simple, sort of the simplest aspect one can write. ;-)

The ugly thing about your sample code is that it uses several classes for which you do not show the source code, so I had to create dummy classes/interfaces in order to make your code compile. You also do not show how the validator is applied, so I have to speculate. Anyway, here is a fully self-consistent set of sample classes:

Helper classes:

This is just scaffolding in order to make everything compile.

package de.scrum_master.app;

public interface Payload {}

package de.scrum_master.app;

public class ConstraintValidatorContext {}

package de.scrum_master.app;

public @interface Constraint {
  Class<MyValidator>[] validatedBy();
}

package de.scrum_master.app;

import java.lang.annotation.Annotation;

public interface ConstraintValidator<T1 extends Annotation, T2> {
  void initialize(T1 annotation);
  boolean isValid(T2 value, ConstraintValidatorContext validatorContext);
}

package de.scrum_master.app;

public class MyValidator implements ConstraintValidator<MyAnnotation, String> {
  @Override
  public void initialize(MyAnnotation annotation) {}

  @Override
  public boolean isValid(String value, ConstraintValidatorContext validatorContext) {
    if ("msg".equals(value))
      return true;
    return false;
  }
}

package de.scrum_master.app;

import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;

import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.*;

@Target({ METHOD, FIELD, PARAMETER })
@Retention(RUNTIME)
@Constraint(validatedBy = { MyValidator.class })
public @interface MyAnnotation {
  String message() default "DEFAULT_FALSE";
  Class<?>[] groups() default {};
  Class<? extends Payload>[] payload() default {};
}

Driver application:

If you want to test something, you do not just need a positive test case, but also a negative one. Because you did not provide that, user Sampisa's answer was not what you were looking for. BTW, I think you should have been able to deduce from it the solution by yourself. You did not even try. Do you not have any programming experience?

package de.scrum_master.app;

public class Application {
  public static void main(String[] args) {
    Application application = new Application();
    System.out.println(application.validate1());
    System.out.println(application.validate2());
  }

  @MyAnnotation(message = "execute me")
  public boolean validate1() {
    return true;
  }

  @MyAnnotation(message = "msg")
  public boolean validate2() {
    return true;
  }
}

Aspect:

The only reason why I add another sample aspect in addition to Sampisa's is that his solution is suboptimal with regard to his reflection usage. It is ugly and it is slow. I think my solution is a bit more elegant. See for yourself:

package de.scrum_master.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class SkipValidationAspect {
  @Around("execution(@de.scrum_master.app.MyAnnotation(message=\"msg\") boolean *(..))")
  public boolean skipValidation(ProceedingJoinPoint thisJoinPoint) throws Throwable {
    return false;
  }
}

Very simple, is it not?

Console log:

true
false

Et voilà - I think this is what you were looking for.

这篇关于自定义 Java 注释以跳过方法执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆