[英]How can I add similar functionality to a number of methods in java?
我有很多日志記錄方法,比如logSomeAction
, logAnotherAction
等。
現在我希望所有這些方法在打印消息(Thread.sleep)后暫停一小段時間。
如果我手動完成,我會做這樣的事情:
//before:
public static void logSomeAction () {
System.out.println (msg(SOME_ACTION));
}
//after:
public static void logSomeAction () {
System.out.println (msg(SOME_ACTION));
try {
Thread.sleep (2000);
} catch (InterruptedException ignored) { }
}
我記得Java有代理類和其他一些魔術制作工具。 有沒有辦法避免將N個睡眠塊復制粘貼到N個記錄方法?
您可以使用Aspects為您的方法添加額外的“正交”功能。
如果這聽起來太深奧,那么更簡單,實際的解決方案是在單獨的方法中添加睡眠,然后在每個記錄方法中調用該方法。 第一次執行此操作時,需要觸摸每個方法,但下次如果要修改額外行為或添加其他內容,則可以在一個位置執行此操作。
看起來您想要使用面向方面編程。 您可以將Spring用於AOP或AspectJ。
OP在評論中提到首選解決方案是使用普通的Java代理。 當前代碼是作為靜態方法實現的 - 對於任何使用的Java代理,記錄器類都需要作為接口重新編寫。 像這樣的東西:
public interface SomeActionLogger
{
void logSomeAction();
void logSomeOtherAction();
// etc..
}
然后,您可以創建具體的實現
public class SystemOutActionLogger implements SomeActionLogger
{
public void logSomeAction () {
System.out.println (msg(SOME_ACTION));
}
}
然后,您可以讓Java代理包裝SomeActionLogger
接口
class DelayAfterInvocationHandler implements InvocationHandler
{
private Object delegate;
private int duration;
DelayAfterInvocationHandler(Object delegate, int duration)
{
this.delegate = delegate;
this.duration = duration;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
Object returnValue = method.invoke(delegate, args);
Thread.sleep(duration);
// you may want to catch InterruptedEception
return returnValue;
}
}
要隱藏一些不那么漂亮的代理代碼,您可以使用一個方法來包裝您的記錄器以創建延遲,例如
public ActionLogger addDelay(SomeActionLogger logger, int delay)
{
return (ActionLogger)Proxy.newProxyInstance(
impl.getClass().getClassLoader(),
new Class[] { SomeActionLogger.class },
new DelayAfterInvocationHandler(logger, delay));
}
所以你然后寫
SomeActionLogger log = addDelay(new SystemOutActionLogger(), 2000);
請注意, DelayInvocationHandler
與日志記錄接口正交 - 它可用於向任何接口添加延遲。 然后,您可以創建一個這樣的通用包裝方法:
public <T> T addDelay(T delegate, int delay, Class<T> interfaceType)
{
return (T)Proxy.newProxyInstance(
delegate.getClass().getClassLoader(),
new Class[] { type },
new DelayAfterInvocationHandler(delegate, delay));
}
創建一個具有靜態SleepFor
方法的實用程序類,該方法包含try ... catch
塊並從您希望睡眠的每個方法中調用它?
替換所有System.out.println(msg(SOME_ACTION)); with printAndWait(SOME_ACTION); 你應該能夠通過查找和替換來做到這一點。 然后創建一個方法
public static void printAndWait(Object someAction) {
System.out.println (msg(someAction));
try {
Thread.sleep (2000);
} catch (InterruptedException ignored) {
Thread.currentThread.interrupt();
}
}
這樣代碼就會顯示一次,您可以在一個地方輕松更改它。
替換所有的logSomeAction()
與一個單一的方法logAction(Action a)
方法。 這樣,當您將來添加更多操作時,您將不會重復代碼來處理操作日志和線程休眠。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.