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

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

问题描述

Java的大师,

我为注释 pretty新的,并没有搜索这个有很多,所以请多多包涵......

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

我想实施自定义注释这将拦截的方法调用;开始与一些非常基本的它可以只打印方法的名称和参数,这样我就能避免记录语句。

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.

一个示例调用是这样的:

A sample call like this:

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?

推荐答案

根据在你我的意见的回答,你将不能够只用注释来做到这一点。你可以,当然,创建你的注释,并创建一些反思code,将检测到的话,并执行一些code,但是这不会改变你的code太多,因为你需要调用解析器方法你打电话给你方法之前,我认为这不会帮助你太多,因为你需要在每次调用前调用解析器方法。

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.

如果你需要,你提到的行为(自动呼叫),您将需要您的注释像春天(普通Java)还是AspectJ(AspectJ的code)一些AOP框架结合起来。有了那么,你可以设置切入点,每次达到这一点,一些code可被执行。然后,您可以配置之前和/或方法执行后,执行一些code。

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:类code测试注释处理

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

    }
}

当然,你需要提高我的code,以满足您的需求。这仅仅是一个起点。

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

更多关于注释:

更多关于AOP:

  • http://en.wikipedia.org/wiki/Aspect-oriented_programming
  • http://static.springsource.org/spring/docs/3.0.x/reference/aop.html
  • http://www.eclipse.org/aspectj/

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

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