2011-03-08 33 views
0

我正在創建內部使用LOG4j的自定義日誌記錄功能類。那些想要使用日誌記錄功能的類,它傳遞了class.i的名字,我想知道我如何能夠限制對象的創建,而不需要將類名傳遞給它。我試過但我不確定這是否是一種正確的方法我做了?如何用某些依賴注入來限制對象創建?

 

public class LoggerObject 
{ 
    private Logger logger; 
    private static LoggerObject loggerobj; 
    private ConstantDataManager constantdatamanger; 

    //Default Log4J_FILE Path 
    private LoggerObject(String className) 
    { 
     try 
     { 
     DOMConfigurator.configure(this.getClass().getClassLoader().getResource(constantdatamanger.LOG4J_FILE)); 
     logger =Logger.getLogger(className); 
     } 
     catch(Exception ex) 
     { 
      System.out.println("DOMConfigurator could not find file"+ex.getMessage()); 
     } 
    } 

    public static LoggerObject getLogger(String className) 
     { 
      if (loggerobj==null) 
      { 
      loggerobj = new LoggerObject(className); 
      } 
      return loggerobj; 
     } 


    public void info(Object message) 
    { 
     logger.info(message); 
    } 

    public void info(Object message, Throwable t) { 
     logger.info(message, t); 
    } 

    public void error(Object message) { 
     logger.error(message); 
    } 

    public void error(Object message, Throwable t) { 
     logger.error(message,t); 
    } 

    public void debug(Object message) { 
     logger.debug(message); 
    } 

    public void debug(Object message, Throwable t) { 
     logger.debug(message,t); 
    } 

    public void warn(Object message) { 
     logger.warn(message); 
    } 

    public void warn(Object message, Throwable t) { 
     logger.warn(message,t); 
    } 

    public void fatal(Object message) { 
     logger.fatal(message); 
    } 

    public void fatal(Object message, Throwable t) { 
     logger.fatal(message,t); 
    } 

感謝

+2

限制如何?同樣,實施slf4j API可能會使您的代碼更具可移植性。 – 2011-03-08 07:15:56

回答

0

LoggerObj是靜態的,因此只存在於類級別。第一次調用getLogger之後,該變量將被初始化,並將繼續將同一對象返回給其他客戶端。

它看起來像你想爲記錄器創建一個工廠,而是創建一個單身?

0

你爲什麼不只是使用Log logger = LogFactory.getLog(className);

如果你想更多的數據會自動添加到日誌,你可以使用你的LoggerObject但也許你應該通過類而不是類名,這樣

class LoggerObject<T> { 
private LoggerObject(Class<T> clazz){ 
    ... 
} 
} 

如果你想限制哪些類已通過,您可以使用class LoggerObject<T extends SomeBaseClass>

編輯:
你應該意識到這一點:

private static LoggerObject loggerobj;  

public static LoggerObject getLogger(String className) 
{ 
    if (loggerobj==null) 
    { 
    loggerobj = new LoggerObject(className); 
    } 
    return loggerobj; 
} 

這將返回正確記錄的第一個電話,然後傳遞className被忽略。

0

將基礎架構邏輯劃分爲獨立實體的主要方法是可測試性。

使用構造函數(或setter)注入,而不是在對象中創建對象,您可以很容易地用mocks替換這個依賴項。但我不認爲你基於記錄器進行測試是最好的選擇。

第二種方法是代碼可移植性,但是作爲@ThorbjørnRavn Andersen已經提到slf4j會更適合這項任務。

0

我不是很確定你想達到什麼目的,在任何情況下,這似乎是錯誤的:

public static LoggerObject getLogger(String className) 
    { 
     if (loggerobj==null) 
     { 
     loggerobj = new LoggerObject(className); 
     } 
     return loggerobj; 
    } 

您實現了一個singleton模式,但是您要存儲傳入(「富」)中的className第一個getLogger調用。這意味着所有後續對getLoggger(「bar」)的調用都將返回一個帶有className「foo」的LoggerObject。如果你想要一個記錄器來統一它們的全部,那麼它的名字可能應該是一個應用程序常量或可配置屬性,而不是恰好由記錄客戶端傳遞的名字。

常規Log4J的成語是:

private static final Logger LOG = Logger.getLogger(abc.xyz.MyLoggingClient.class); 

這將創建參數的完全合格的類名作爲其名稱的記錄器。在log4j中。物業你會有這樣的東西:

log4j.logger.abc.xyz.MyLoggingClient=WARN 

請解釋一下,你真的想要實現,你不能用普通的Log4j做。