将代码插入到主执行块之前和之后的方法中

问题描述 投票:1回答:1

我有几个实现特定的interface的类,如下所示(这显然是一个非常简化的版本,但很清楚):

public interface Talk {
  void sayIt();
}

Talk的第一个实现:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SayHello implements Talk {

  static final Logger LOG = LoggerFactory.getLogger(SayHello.class);

  public SayHello() {}

  public void sayIt() {
    System.out.println("Hello");
  }
}

Talk的第二种实现:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SayGoodbye implements Talk {

  static final Logger LOG = LoggerFactory.getLogger(SayHello.class);

  public SayGoodbye() {}

  public void sayIt() {
    System.out.println("GoodBye");
  }

}

现在在sayIt()方法中,我想实现一些跟踪级别的日志记录和一些方法执行计时器,我可以简单地执行以下操作:

public void sayIt() {
    long startTime = System.currentTimeMillis();
    LOG.trace("Executing sayIT for implementation {} , start time at {}.", this.getClass().getSimpleName(), startTime);
    System.out.println("Hello");
    LOG.trace("sayIT for implementation {} took {} milliseconds to execute.", this.getClass().getSimpleName(), System.currentTimeMillis() - startTime);
}

问题是我需要将实现复制并粘贴到实现sayIt()接口的每个classTalk方法的每个实现中,而我真的不想这样做,因为...

  1. 它会产生很多重复。
  2. 随着更多的实现,您开始会遇到维护上的麻烦,尤其是当您决定稍微更改实现时。
  3. 我很懒,喜欢编写尽可能少的代码,同时尽可能多地重用。

所以这是问题...。我将如何实现一次编写,多次使用的目标?方法计时是一个应用程序,但是我真的只是希望能够在方法的开始和结束处“注入”代码。

我真的是在寻找一个[[工作示例(不仅仅是指向更多链接的链接)”,这些东西可能会起作用(我猜是AspectJ之类的东西,但是我一直在无休止地试图让它与Gradle一起使用...可能只是尝试了Maven实现)

哦,是的,我可以代替将代码添加到sayIt()中,而不是将其添加到调用sayIt()的代码中,例如:

import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; public class SomeOtherClass { static final Logger LOG = LoggerFactory.getLogger(SomeOtherClass.class); public SomeOtherClass() {} public void letsHaveAConversation() { List<Talk> talks = new ArrayList<>(); talks.add(new SayHello()); talks.add(new SayGoodbye()); for (Talk talking : talks) { long startTime = System.currentTimeMillis(); LOG.trace("Executing sayIT for implementation {} , start time at {}.", talking.getClass().getSimpleName(), startTime); talking.sayIt(); LOG.trace("sayIT for implementation {} took {} milliseconds to execute.", talking.getClass().getSimpleName(), System.currentTimeMillis() - startTime); } } }

这将起作用,但是如果我有多个要从中调用sayIt()的位置,则不会。 
java performance code-injection
1个回答
0
投票
为什么不只将sayIt调用包装在抽象类通用方法中?

abstract class AbstractTalk implements Talk { public void sayIt() { trace(); startMeasure(); doSayIt(); stopMeasure(); } abstract protected doSayIt(); // here implement the logic }

© www.soinside.com 2019 - 2024. All rights reserved.