2017-02-28 41 views
1

我想创建一个自定义的注释跳过方法执行自定义Java注释跳过方法执行

这是我的注释代码,以验证类

@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; 


    } 
} 
+3

您需要更改'如果(STR ==“味精”){'使用'等于()' –

+0

怎么会是“跳跃”的事情将要发生? –

+0

嗨,那是我的问题,如果有可能使用这种验证,我不知道,如果是可以做到的 –

回答

2

它其实很简单,可以写成最简单的方面。 ;-)

关于您的示例代码的丑陋之处在于它使用了几个不显示源代码的类,所以我必须创建虚拟类/接口才能编译代码。你也不会展示验证器是如何应用的,所以我必须推测。总之,这里是一个完全自我一致的样本类:

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 

的Et瞧 - 我想这就是你要找的人。

+0

aye atain队长...我看到的最好的答案之一stackoverflow.com –

+0

这工作正如我所料 –

+0

我只是编辑的两个答案的方面点点,组合 –

3

您应该使用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,如果你想 。事实上,我认为这一点很明确。

+0

后你好,这是一些我想做的,但我厌倦了这一点,执行流程甚至没有进入方面课,你是否错过了这里的东西..? –

+0

我真正想要的是跳过方法执行的方法 - 验证,你在示例中注释 - 用@MyAnnotation(“doh”) –

+1

如果它不适合你,**你**错过了一些东西,而不是@Sampisa。你可以学习如何以有意义的方式提出问题,这也表达了你的实际意图? – kriegaex