问题描述
我想创建一个自定义批注以跳过方法执行
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:
帮助程序类:
这只是为了使所有内容都能编译的脚手架.
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 {};
}
驱动程序应用程序:
如果您要测试某些东西,则不仅需要一个肯定的测试用例,还需要一个否定的用例.因为您没有提供,所以Sampisa用户的答案不是您想要的.顺便说一句,我认为您应该能够自己推断出解决方案.您甚至都没有尝试.您没有任何编程经验吗?
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;
}
}
方面:
除了桑皮萨(Sampisa)之外,我还添加了另一个示例方面的唯一原因是,就他的反射用法而言,他的解决方案是次优的.这很丑,很慢.我认为我的解决方案更加优雅.亲自看看:
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;
}
}
很简单,不是吗?
控制台日志:
true
false
Etvoilà-我想这就是您想要的.
Et voilà - I think this is what you were looking for.
这篇关于自定义Java批注可跳过方法执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!