我想创建一个自定义的注释跳过方法执行
这是我的注释代码,以验证类
@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{};
}
我与验证尝试过。 这是我的验证的样子
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;
}
}
这是我要如何使用 - 我想使用方法级的注释和跳过方法执行。
我不知道这是否是可能的。请帮助。
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;
}
}
这其实是很简单的,那种可以写出最简单的方面。 ;-)
关于你的示例代码中的丑陋的东西是,它使用了几个类,你不显示的源代码,所以我不得不为了使你的代码编译创建虚拟类/接口。 您还没有显示的验证是如何应用的,所以我不得不猜测。 总之,这里是一个完全自我一致的样本类:
Helper类:
这只是脚手架为了使一切编译。
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的答案是不是你所期待的。 顺便说一句,我想你应该已经能够自己从中推导出解决方案。 你甚至没有尝试。 你没有任何编程经验?
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添加另一个示例方面的唯一原因是,他的解决方案是最理想的关于自己的倒影使用。 这是丑陋的,它是缓慢的。 我想,我的解决办法是更优雅一点。 你自己看:
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
等瞧 - 我想这就是你要找的人。
您应该使用AOP了点。 创建一个AspectJ项目,并尝试是这样的:
MyAnnotation.java:
package moo.aspecttest;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(value = { ElementType.METHOD })
public @interface MyAnnotation
{
public String value();
}
MyAspectClass.java:
package moo.aspecttest;
import java.lang.reflect.Method;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
@Aspect
public class MyAspectClass
{
@Around("execution(* *(..))")
public Object aroundAdvice(ProceedingJoinPoint point) throws Throwable
{
Method method = MethodSignature.class.cast(point.getSignature()).getMethod();
String name = method.getName();
MyAnnotation puff = method.getAnnotation(MyAnnotation.class);
if (puff != null) {
System.out.println("Method " + name + " annotated with " + puff.value() + ": skipped");
return null;
} else {
System.out.println("Method " + name + " non annotated: executing...");
Object toret = point.proceed();
System.out.println("Method " + name + " non annotated: executed");
return toret;
}
}
}
MyTestClass.java:
package moo.aspecttest;
public class MyTestClass
{
@MyAnnotation("doh")
public boolean validate(String s) {
System.out.println("Validating "+s);
return true;
}
public boolean validate2(String s) {
System.out.println("Validating2 "+s);
return true;
}
public static void main(String[] args)
{
MyTestClass mc = new MyTestClass();
mc.validate("hello");
mc.validate2("cheers");
}
}
}
当你运行它生成的输出:
Method main non annotated: executing...
Method validate annotated with doh: skipped
Method validate2 non annotated: executing...
Validating2 cheers
Method validate2 non annotated: executed
Method main non annotated: executed
我用了一个很普通的aroundAdvice, 但你可以用一个beforeAdvice,如果你想要的 。 事实上,我觉得这一点是明确的。