Spring - 在没有明确规范的情况下注入Log4j记录器

时间:2018-04-30 12:45:42

标签: java spring dependency-injection log4j

我使用基于Spring XML的DI来创建我的类。

我也使用log4j,并且我在每个需要它的类中注入org.apache.log4j.Logger作为构造函数参数。

所以我在Spring配置中有很多条目如下:

<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默认为类名,其构造函数应该将创建的记录器传递给它?

E.g。对于Unity DI和log4net来说就像这个solution,它们在.Net中是类似的。

更新

我看到注入Logger而不是在类中初始化它的两个原因。

首先,像private final Logger logger = LogManager.getLogger(MyClass.class);这样的语句通常是复制粘贴的,因此它们在记录器名称中容易出错。

Moverover,我想通过单元测试覆盖错误记录,例如:将Logger的模拟传递给构造函数,然后验证在调用了一些错误操作logger.Error之后。

1 个答案:

答案 0 :(得分:0)

将记录器作为构造函数参数传递有点可怕。 另外,你反对使用private ...blah... Logger的论据是似是而非。

  1. &#34;复制粘贴容易出错。&#34; 真正的复制粘贴技术容易出错, 但是当你希望每个记录器都有一个唯一的名称(以便识别日志消息的来源)时, 你需要在每个类中声明一个记录器。
  2. &#34;我想在单元测试中模拟我的记录器。&#34; 虽然用mock替换最终成员变量是不合理的, 用mock替换一个非最终成员变量是非常容易的。 为此, 您应该始终声明类级别记录器:private static Logger ...blah。 特别, 不要使用最终记录器。 一旦记录器不是最终的, 用反射代替模拟。