Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 记录方法入口和出口的设计模式?_Java_Design Patterns - Fatal编程技术网

Java 记录方法入口和出口的设计模式?

Java 记录方法入口和出口的设计模式?,java,design-patterns,Java,Design Patterns,我有一个总体设计和架构问题。在研究了设计模式(装饰器、命令链等)之后,我仍然不清楚 要求: 我希望必须记录我的方法的入口和出口 到目前为止,我所有的方法都是这样的: public SomeReturnType someMethod1( SomeParameter someParameter ) { LOGGER.info( "{someMethod1}[START someMethod1 compute]" ); doSomeComputationFor(someParamet

我有一个总体设计和架构问题。在研究了设计模式(装饰器、命令链等)之后,我仍然不清楚

要求: 我希望必须记录我的方法的入口和出口

到目前为止,我所有的方法都是这样的:

public SomeReturnType someMethod1( SomeParameter someParameter ) {
    LOGGER.info( "{someMethod1}[START someMethod1 compute]" );

    doSomeComputationFor(someParameter);
    SomeReturnType result = getSomeResult();

    LOGGER.info( "{someMethod1}[END someMethod1 compute]" );

    return result;
}

public SomeOtherReturnType someMethod2( SomeOtherParameter someOtherParameter ) {
    LOGGER.info( "{someMethod2}[START someMethod2 compute]" );

    maybeDoSomeDBOperation(someOtherParameter);
    SomeOtherReturnType result = getSomeOtherResult();

    LOGGER.info( "{someMethod2}[END someMethod2 compute]" );

    return result;
}
(在日志下面,我还使用一些KPI库来发送一些时间戳,比如StatsD)

所有结构实际上都具有以下形式:

public Foo method( Bar bar ) {
    //1 do some logging as the method starts, and also send some KPI
    LOGGER.info( "{method}[START method compute]" );

    //2 do some computation and actual business logic

    //3 do some logging the confirm the mothods has reached the end + send some other KPI like time elapsed
    LOGGER.info( "{method}[END method compute]" );

    return result;
}
现在,看看我的项目,我有大约290种方法遵循完全相同的结构


有没有聪明的方法来解决这个问题?也许有一个漂亮的图案?一些注释?方面?我愿意接受建议,因为我相信肯定有比我目前的解决方案更好的解决方案。

一个可能的解决方案是使用依赖项注入器+注释

这里有一个关于如何在JavaSE应用程序中实现所需内容的示例

您需要添加此依赖项:


org.jboss.weld.se


注意:如果您在JavaEE项目中,所有与焊接创建相关的内容都由您的容器管理。

这听起来与某个方面的用例完全相同。这个案例也使用Kleisli类别解决了(请参阅C++中的精彩演示)
package org.loggable;

import javax.interceptor.InterceptorBinding;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE, ElementType.METHOD})
@Inherited
@InterceptorBinding
@Retention(RetentionPolicy.RUNTIME)
public @interface Loggable {
}
package org.loggable;

import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;
import java.util.logging.Logger;

@Loggable
@Interceptor
public class LoggableInterceptor {

    @AroundInvoke
    public Object logMethod(InvocationContext context) throws Exception {
        Logger logger = Logger.getLogger(context.getTarget().getClass().getSimpleName());

        logger.info("Starting method: " + context.getMethod().getName());
        Object response = context.proceed();
        logger.info("Finished method: " + context.getMethod().getName());
        return response;

    }
}
package org.loggable;

import javax.enterprise.inject.se.SeContainer;
import javax.enterprise.inject.se.SeContainerInitializer;
import java.io.IOException;
import java.util.logging.Logger;

public class Main {
    public static void main(String... args) throws IOException {
        SeContainer seContainer = SeContainerInitializer.newInstance()
                .initialize();

        Main main = seContainer.select(Main.class).get();
        main.loggableMethod();

        seContainer.close();
    }


    @Loggable
    public void loggableMethod() {
        Logger.getLogger(Main.class.getSimpleName()).info("Inside method.");
    }
}

[2019-04-06 11:07:20] [INFO   ] Starting method: loggableMethod 
[2019-04-06 11:07:20] [INFO   ] Inside method. 
[2019-04-06 11:07:20] [INFO   ] Finished method: loggableMethod