具有动态参数的自定义注释

时间:2014-01-17 12:48:45

标签: java spring spring-annotations

这是我的问题:

我有一个注释:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DummyAnnotation {
String dummyParam1();
String dummyParam2();
}

我的服务是:

@Component
public class DummyService {

@DummyAnnotation(dummyParam1="#otp",dummyParam2="#transactionId")
public void dummy(String otp, String transactionId){

}
}

我的方面是尝试验证这两个参数,如果验证没有成功则抛出异常:

 @Around(value = "@annotation(annotation)")
public Object verifyOtp(final ProceedingJoinPoint jointPoint, final DummyAnnotation  annotation) throws Throwable {
            String transactionId = annotation.dummyParam1();
            String otp = annotation.dummyParam2();
            Boolean otpValid = otpService.verify(transactionId, otp);
            if (otpValid) {
                return jointPoint.proceed();
            }
            else {
                throw new AuthentificationForteException();
            }

}

我怎样才能使这个工作,因为Spring EL不起作用,而且在我的方面我有 dummyAnnotation.dummyParam1()等于“#otp”而不是我的参数String otp的值。

提前致谢。

2 个答案:

答案 0 :(得分:1)

不会写一个与此相反的方面更简单吗?

@DummyAnnotation
public void dummy(@Otp String otp, @TransactionId String transactionId){
  ...
}

它也不是特定于Spring的,因此更容易测试。

(如果你打算遍历提取OTP或TX ID的参数,例如#foo.txId,那么这当然不会起作用,但我认为它更简单。)

答案 1 :(得分:0)

Finnaly我找到了解决方案:

解决方案是实现特定的Spring El Expression Parser Idd在我的方面添加了这些声明:

private ExpressionParser expressionParser = new SpelExpressionParser();
private ParserContext parserContext = new TemplateparserContext();

我改变了如何检索dummyValue:

@Around(value = "@annotation(annotation)")
public Object verifyOtp(final ProceedingJoinPoint jointPoint, final DummyAnnotation  annotation) throws Throwable {

String transactionId = getDummyValue(annotation.dummyParam1(),jointPoint.getArgs());
String otp = getDummyValue(annotation.dummyParam2(),jointPoint.getArgs());

        Boolean otpValid = otpService.verify(transactionId, otp);
        if (otpValid) {
            return jointPoint.proceed();
        }
        else {
            throw new AuthentificationForteException();
        }

}

getDummyValue是一个解析表达式的方法:

private String getDummyValue(String authExpression,  Object[] args){
    Expression expression = expressionParser.parseExpression(authExpression, parserContext);
    String value = expression.getValue(new RootObject(args),String.class);
    return value;
}


private static class TemplateparserContext implements ParserContext{

    @Override
    public boolean isTemplate() {
        return true;
    }

    @Override
    public String getExpressionPrefix() {
        return "#{";
    }

    @Override
    public String getExpressionSuffix() {
        return "}";
    }

}

 protected static class RootObject {

        private final Object[] args;

        private RootObject(Object[] args) {
            super();
            this.args = args;
        }

        public Object[] getArgs() {
            return args;
        }
    }

和finallity我改变我的服务和使用DummyAnnotation:

 @Component
 public class DummyService {

 @DummyAnnotation(dummyParam1="#{args[0]}",dummyParam2="#{args[1]}")
 public void dummy(String otp, String transactionId){

 }
 }