我正在创建一个具有自定义日志功能的类,它在内部使用Log4J。
如果一个类需要日志记录功能,我就把这个类的名称传递给这个LoggerObject
的构造函数。
我想知道如何在不传递类名的情况下限制对象的创建。我尝试了一种解决方案,但我不确定这是实现这一点的正确方法。
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);
}
}
字符串
谢谢
4条答案
按热度按时间daupos2t1#
LoggerObj是静态的,因此只存在于类级别。在第一次调用getLogger之后,变量被初始化,并将继续向其他客户端返回相同的对象。
看起来你想为记录器创建一个工厂,但却创建了一个单例?
vuv7lop32#
为什么不直接用
Log logger = LogFactory.getLog(className);
呢?如果您想自动向日志中添加更多数据,可以使用LoggerObject,但也许应该传递类而不是类名,如下所示
字符串
如果你想限制传递哪些类,可以使用
class LoggerObject<T extends SomeBaseClass>
。编辑:
你应该知道这一点:
型
这将为第一次调用返回正确的记录器,然后忽略传递的
className
。7z5jn7bk3#
划分基础结构逻辑以分离实体的主要方法是可测试性。
使用构造函数(或setter)注入而不是在对象中创建对象,你可以很容易地用mocks替换这种依赖。但我不认为基于logger的测试是最好的选择。
第二种方法是代码可移植性,但是正如 @Thorbjørn Ravn Andersen 已经提到的,slf4j将更适合这项任务。
p8ekf7hl4#
我不完全确定你想达到什么目的,无论如何,这似乎是错误的:
字符串
你实现了一个singleton模式,但是你存储的是第一个getLogger调用中传递的className(“foo”)。这意味着所有对getLogger(“bar”)的后续调用都将返回一个className为“foo”的LoggerObject。如果你想让一个logger来统治所有的logger,那么它的名字可能应该是一个应用常量或可配置的属性,而不是碰巧被日志客户端传递的第一个名字。
Log4J的标准用法是:
型
这将创建一个以参数的完全限定类名作为其名称的记录器。在log4j.properties中,您将拥有以下内容:
型
请解释你到底想实现什么,你不能用普通的Log4j。