Spring -注入Log4j logger,没有显式规范

nzkunb0c  于 2023-08-02  发布在  Spring
关注(0)|答案(1)|浏览(92)

我使用基于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被调用之后。

ftf50wuq

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。

相关问题