自定义注释作为方法记录的拦截器 [英] Custom annotation as Interceptor for a method logging

查看:21
本文介绍了自定义注释作为方法记录的拦截器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Java 大师,

我对 annotations 很陌生,并且没有大量搜索过,所以请多多包涵...

I am pretty new for annotations and haven't searched for this a lot, so please bear with me...

我想实现一个Custom Annotation,它将拦截一个方法调用;从一些非常基本的东西开始,它可以只打印方法名称和参数,这样我就可以避免 logger 语句.

I would like to implement a Custom Annotation which will intercept a method call; to start with something very basic it can just print the methods name and parameters so that I could avoid the logger statement.

这样的示例调用:

public MyAppObject findMyAppObjectById(Long id) throws MyCustomException {
    log.debug("in findMyAppObjectById(" + id + ")");
    //....
}   

可以转化为:

@LogMethodCall(Logger.DEBUG)
public MyAppObject findMyAppObjectById(Long id) throws MyCustomException {
    //....
}   

我能得到一些关于这个的提示吗?

Could I get some hints about this?

推荐答案

根据您对我评论的回答,您将无法仅使用注释来执行此操作.当然,您可以创建注释并创建一些反射代码,然后检测并执行一些代码,但这不会对您的代码进行太多更改,因为您需要先调用 parser 方法你调用你的方法,我认为这对你没有太大帮助,因为你需要在每次调用之前调用解析器方法.

Based in your answers of my comments, you will not be able to do this with just annotations. You can, of course, create your annotations and create some reflective code that will detected then and execute some code, but this will not change your code too much, because you will need to call the parser method before you call your methods and I think that will not help you too much, since you will need to call the parser method before each call.

如果您需要您提到的行为(自动调用),您需要将您的注释与一些 AOP 框架结合起来,例如 Spring(纯 Java)或 AspectJ(AspectJ 代码).然后,您可以设置切入点,每次到达该点时,可能会执行一些代码.您可以配置 then 在方法执行之前和/或之后执行一些代码.

If you need the behavior that you mentioned (automatic call), you will need to combine your annotations with some AOP framework like Spring (plain Java) or AspectJ (AspectJ code). With then, you can set pointcuts and everytime this point is reached, some code may be executed. You can configure then to execute some code before and/or after method execution.

如果第一个场景足够了,你可以这样做:

If the first scenario is sufficient, you can do something like:

记录器:枚举

public enum Logger {
    INFO,
    DEBUG;
}

LogMethodCall:注释

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention( RetentionPolicy.RUNTIME ) // the annotation will be available during runtime
@Target( ElementType.METHOD )         // this can just used in methods
public @interface LogMethodCall {

    Logger logLevel() default Logger.INFO;

}

人物:带注释的类

public class Person {

    // will use the default log level (INFO)
    @LogMethodCall
    public void foo( int a ) {
        System.out.println( "foo! " + a );
    }

    @LogMethodCall( logLevel = Logger.DEBUG )
    public void bar( int b ) {
        System.out.println( "bar! " + b );
    }

}

Utils:带有日志静态方法的类(这将执行解析")

public class Utils {

    public static void log( Object o, String methodName ) {

        // gets the object class
        Class klass = o.getClass();

        // iterate over its methods
        for ( Method m : klass.getMethods() ) {

            // verify if the method is the wanted one
            if ( m.getName().equals( methodName ) ) {

                // yes, it is
                // so, iterate over its annotations
                for ( Annotation a : m.getAnnotations() ) {

                    // verify if it is a LogMethodCall annotation
                    if ( a instanceof LogMethodCall ) {

                        // yes, it is
                        // so, cast it
                        LogMethodCall lmc = ( LogMethodCall ) a;

                        // verify the log level
                        switch ( lmc.logLevel() ) {
                            case INFO:
                                System.out.println( "performing info log for "" + m.getName() + "" method" );
                                break;
                            case DEBUG:
                                System.out.println( "performing debug log for "" + m.getName() + "" method" );
                                break;
                        }

                    }
                }

                // method encountered, so the loop can be break
                break;

            }

        }

    }

}

AnnotationProcessing:带有用于测试注释处理的代码的类

public class AnnotationProcessing {

    public static void main(String[] args) {

        Person p = new Person();
        Utils.log( p, "foo" );
        p.foo( 2 );
        Utils.log( p, "bar" );
        p.bar( 3 );

    }
}

当然,您需要改进我的代码以满足您的需求.这只是一个起点.

Of course, you will need to improve my code to fit your needs. It is just a start point.

关于注释的更多信息:

更多关于 AOP:

这篇关于自定义注释作为方法记录的拦截器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆