当前位置: 首页 > 面试题库 >

自定义注释作为方法记录的拦截器

桂坚
2023-03-14
问题内容

Java专家

我很新annotations,还没有搜索很多,所以请忍受…

我想实现一个Custom Annotationintercept调用方法的方法;从最基础的东西开始,它可以只打印方法名称和参数,这样我就可以避免使用该logger语句。

像这样的示例调用:

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

可以转换为:

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

我可以得到一些提示吗?


问题答案:

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

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

如果第一种情况足够,则可以执行以下操作:

记录器:枚举

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

}

实用程序:具有日志静态方法的类(将执行“解析”)

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

    }
}

当然,您将需要改进我的代码以适合您的需求。这只是一个起点。

有关注释的更多信息:

  • http://docs.oracle.com/javase/1.5.0/docs/guide/language/annotations.html
  • http://docs.oracle.com/javase/tutorial/java/javaOO/annotations.html
  • http://tutorials.jenkov.com/java-reflection/annotations.html

有关AOP的更多信息:

  • http://zh.wikipedia.org/wiki/面向方面的编程
  • http://static.springsource.org/spring/docs/3.0.x/reference/aop.html
  • http://www.eclipse.org/aspectj/


 类似资料:
  • 我正在编写一个库/sdk,它可以拦截任何使用自定义注释进行注释的方法。代码的工作方式有点像这样 截取这个的方面有一个切入点表达式 当我在与相同的包中描述方面时,此代码工作正常。但是,如果我创建一个单独的库并定义方面,因为它无法拦截。有帮助吗? 回应@Bond的评论 Spring版本:Spring上下文-4.1.7。发布aspectj-1.6.5问题的关键是注释不会在同一个项目中使用。在编译之后,它

  • 我试图在Karaf中定义和使用自定义运行时注释。它不适合我。 我可以将包配置为使用Pax CDI OpenWebBeans CDI容器。集装箱很好用。我可以看到公开的服务(standard annotation@OsgiServiceProvider)。 但对于已定义的@AroundInvoke方法的自定义拦截器标记,它不处理使用自定义注释方法进行注释的拦截器标记。 我使用apache-karaf

  • 我试图让aspectj拦截带注释的方法: 我删除了!为了简洁起见,在(InterceptMeAspect)内,但它并没有拦截太多。如果我删除注释约束(在(@InterceptMe*)内),它可以工作,但会拦截所有内容,这会造成一个大问题。 输出字节码似乎有完整的注释,所以我希望注释标准匹配。我正在或试图进行编译时编织。这很重要,因为我有另一个方面确实使用上面相同的方法工作。我怀疑该方面正在搞乱这个

  • 我的服务界面如下所示。 我希望保留在接口级别定义的注释,而不是方法实现。有办法得到这份工作吗?

  • 本文向大家介绍SpringBoot拦截器实现登录拦截的方法示例,包括了SpringBoot拦截器实现登录拦截的方法示例的使用技巧和注意事项,需要的朋友参考一下 源码 GitHub:https://github.com/291685399/springboot-learning/tree/master/springboot-interceptor01 SpringBoot拦截器可以做什么 可以对UR

  • null 我尝试将@priority(interceptor.priority.platform_beform)和@prematching也放入我的过滤器中,但即使是在OIDC启动后也会调用。 另外,是否有任何方法支持扩展quarkus oidc逻辑以包括自定义代码? 我无法获得oidc和keycloak-auth拦截器的优先级(知道这些可以帮助我决定过滤器的优先级)。请帮忙。