SiB*_*SiB 24 java logging annotations interceptor
Java大师,
我很新,annotations并没有搜索过这个,所以请耐心等待...
我想实现Custom Annotation这将intercept一个方法调用.从非常基本的东西开始,它可以只打印方法名称和参数,以便我可以避免使用该logger语句.
像这样的示例调用:
public MyAppObject findMyAppObjectById(Long id) throws MyCustomException {
log.debug("in findMyAppObjectById(" + id + ")");
//....
}
Run Code Online (Sandbox Code Playgroud)
可以转换成:
@LogMethodCall(Logger.DEBUG)
public MyAppObject findMyAppObjectById(Long id) throws MyCustomException {
//....
}
Run Code Online (Sandbox Code Playgroud)
我可以得到一些关于此的提示吗?
dav*_*tto 37
根据您对我的评论的回答,您将无法仅使用注释来执行此操作.当然,您可以创建注释并创建一些反射代码,然后检测并执行一些代码,但这不会过多地更改代码,因为在调用parser方法之前需要调用方法,我认为不会帮助你太多,因为你需要在每次调用之前调用解析器方法.
如果您需要您提到的行为(自动调用),则需要将注释与一些AOP框架(如Spring(普通Java)或AspectJ(AspectJ代码))结合使用.然后,您可以设置切入点,每次到达此点时,都可能会执行某些代码.然后,您可以配置在方法执行之前和/或之后执行某些代码.
如果第一个场景足够,您可以执行以下操作:
记录器:枚举
public enum Logger {
INFO,
DEBUG;
}
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
人:注释类
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 );
}
}
Run Code Online (Sandbox Code Playgroud)
Utils:带有log static方法的类(这将执行"解析")
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;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
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 );
}
}
Run Code Online (Sandbox Code Playgroud)
当然,您需要改进我的代码以满足您的需求.这只是一个起点.
有关注释的更多信息:
关于AOP的更多信息:
Ari*_*aha 20
使用Spring AOP和Java Annotation.Spring AOP否定了使用Java Reflection编写用于解析Java类的util类的要求.
示例 -
自定义注释 -
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface A {
boolean startA() default false;
boolean endA() default false;
}
Run Code Online (Sandbox Code Playgroud)方面-
@Aspect
public class AAspect {
@Pointcut(value = "execution(* *.*(..))")
public void allMethods() {
LOGGER.debug("Inside all methods");
}
@Before("allMethods() && @annotation(A)")`
public void startAProcess(JoinPoint pjp, A a) throws Throwable {
if (a.startA()) {
//Do something
}
}
Run Code Online (Sandbox Code Playgroud)启用AspectJ -
@Configuration
@EnableAspectJAutoProxy
public class AConfig {
}
Run Code Online (Sandbox Code Playgroud)在代码中使用 -
@A(startA = true, endA = true)
public void setUp(){
//Do something- logic
}
Run Code Online (Sandbox Code Playgroud)正如已经建议的,AOP 和注释是最好的选择。我建议使用jcabi-aspects的现成机制(我是开发人员):
@Loggable(Loggable.DEBUG)
public String load(URL url) {
return url.openConnection().getContent();
}
Run Code Online (Sandbox Code Playgroud)
所有方法调用都将记录到 SLF4J。
| 归档时间: |
|
| 查看次数: |
44249 次 |
| 最近记录: |