简体   繁体   English

Java 自定义注解——带注解调用方法

[英]Java custom annotation - calling methods with annotation

I have two annotation (@Translation, @Translate).我有两个注释(@Translation,@Translate)。

@Retention(RUNTIME)
@Target({FIELD})
public @interface Translation {
}

@Retention(RUNTIME)
@Target({PARAMETER})
public @interface Translate {
}

With @Translation I want to mark some fields like below使用@Translation,我想标记一些字段,如下所示

class User {
   @Translation
   String name;
}

And I have Injector class that implementing @Translation.而且我有实现@Translation 的喷油器class。

>   public class Injector {
    public void inject(Object instance) {
        Class clazz = instance.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(Translation.class)) {
                Translation set = field.getAnnotation(Translation.class);
                // set value to fields
            }
        }
    }
}

I want to execute method inject with @Translate like我想用@Translate 执行方法注入

class UserDto{

String name;

void UserDto(@Translate User user){
    name = user.name;
}

If I asked something wrong, please correct me.如果我问错了什么,请纠正我。 Thank you for your advice.感谢您的意见。

As far as I know, you need to use aspect-oriented programming (SpringAOP) to take some action before the method invocation and validating parameter annotated with @Translate.据我所知,在方法调用和验证带有@Translate 注释的参数之前,您需要使用面向方面的编程(SpringAOP)来采取一些行动。

On the other hand, you could implement the method, that validates @Translate annotation as you did with @Translation and invoke it in the constructor.另一方面,您可以实现该方法,该方法验证 @Translate 注释,就像您对 @Translation 所做的那样,并在构造函数中调用它。

First off Spring AOP(proxy based) works with intercepting method invocations only.首先 Spring AOP(基于代理)仅适用于拦截方法调用。 The following Aspect is triggered whenever the annotation is incountered on a method (in your case you can use setters).每当在方法上遇到注释时都会触发以下方面(在您的情况下,您可以使用 setter)。 Particularly @Around executes on entry and exist of a particular method.特别是@Around在特定方法的入口和存在时执行。 It should be more or less similar to the following.它应该或多或少类似于以下内容。 Note I have used List of String to capture the method arguments.注意我使用List of String来捕获方法 arguments。

@Aspect
@Component
public class TranslateAspect {

    Logger logger = LoggerFactory.getLogger(TranslateAspect.class);
    
    //The argument ProceedingJoinPoint will be an executing **method** which has been annotated with @Translation. 
    @Around("@annotation(your.package.Translation)")
    public Object translationInterceptor(ProceedingJoinPoint jointPoint) throws Throwable {
        List<String> arguments = new ArrayList<>(); //may be add a map
        String declaringMethod = TranslateAspect.class.getSimpleName();
        Object proceed = null;
        try{
            MethodSignature methodSignature = (MethodSignature) jointPoint.getSignature();
            Method method = methodSignature.getMethod();
            declaringMethod = methodSignature.getDeclaringType().getSimpleName() + "." + method.getName() + "()"; //like clazz.methodName()
            
            //argument name and value
            String[] argumentNames = methodSignature.getParameterNames();
            Object[] methodArguments = jointPoint.getArgs();
                        
            //add name and value of each parameter
            for(int i=0; i < methodArguments.length; i++){
                arguments.add(argumentNames[i] + " = " + methodArguments[i]);
            }
            
            proceed = jointPoint.proceed();
        }catch (Exception e) {
            throw e; //should not swallow the thrown exception
        }finally {
            // add logging?
        }
        return proceed;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM