我使用基于Spring XML的DI来创建我的类。
我还使用了log4j,并将org.apache.log4j.Logger
作为构造函数参数注入到每个需要它的类中。
所以我在Spring config中有很多条目,如下所示:
<bean id="myClass" class="com.myProject.MyClass">
...
<constructor-arg type="org.apache.log4j.Logger">
<bean class="org.apache.log4j.Logger" factory-method="getLogger">
<constructor-arg value="com.myProject.MyClass"/>
</bean>
</constructor-arg>
</bean>
字符串
分类代码:
package com.myProject;
import org.apache.log4j.Logger;
public class MyClass {
private final Logger logger;
public MyClass (
...
Logger logger) {
...
this.logger = logger;
}
...
}
型
虽然它工作得很好,但我想知道是否有可能将记录器的constructor-arg
默认为类名,创建的记录器应该传递给谁的构造函数?
例如,Unity DI和log4net的solution在. Net中有些类似。
更新:
我看到了注入Logger
而不是在类内部初始化它的两个原因。
首先,像private final Logger logger = LogManager.getLogger(MyClass.class);
这样的语句通常是复制粘贴的,所以它们很容易在记录器名称中出错。
此外,我想在单元测试中涵盖错误日志记录,例如。将Logger
的mock传递到构造函数中,然后验证在某些错误的操作logger.Error
被调用之后。
1条答案
按热度按时间ftf50wuq1#
将记录器作为构造函数参数传递有点糟糕。此外,您反对使用
private ...blah... Logger
的论点也是似是而非的。1.“copy-paste is error paste.”真正的copy-paste技术是容易出错的,但是当您希望每个日志记录器都有一个唯一的名称(以便标识日志消息的来源)时,您需要在每个类中声明一个日志记录器。
1.“我想在单元测试期间模拟我的记录器”。虽然用mock替换final成员变量是不合理的,但是用mock替换非final成员变量却非常容易。为此,您应该始终声明类级别的记录器如下:
private static Logger ...blah
。具体来说,不要使用final logger。一旦记录器不是最终的,就使用反射将它们替换为模拟。1.【2023年新增; hurry for learnin ']使用受保护的记录器。将你的logger声明为
static Logger ...blah
,然后在Junit(jupiter)单元测试中将它分配给@BeforeEach
或@BeforeAll
方法中的mockLogger。