java在单元测试中lombok示例化之前加载spring引导组件

a6b3iqyw  于 2021-07-24  发布在  Java
关注(0)|答案(2)|浏览(400)

我开发了一种 Package 器,让它作为一个定制的记录器工作。我正在使用 @CustomLog lombok注解只是为了让它更简单更干净。接下来是一件棘手的事情:这个 Package 器背后的想法是使用一个公共记录器(如 org.slf4j.Logger )以及每次调用 log.error() ,正确的消息被记录在终端中,事件被发送到我的监控工具(本例中是prometheus)。
为了实现这一点,我上了以下课程: CustomLoggerFactory lombok调用工厂来示例化我的自定义记录器。

public final class CustomLoggerFactory {

     public static CustomLogger getLogger(String className) {

        return new CustomLogger(className);
     }
}
``` `CustomLogger` 会收到类名才调用 `org.slf4j.LoggerFactory` .

public class CustomLogger {

private org.slf4j.Logger logger;
private PrometheusMonitor prometheusMonitor;
private String className;

public CustomLogger(String className) {

    this.logger = org.slf4j.LoggerFactory.getLogger(className);
    this.className = className;
    this.monitor = SpringContext.getBean(PrometheusMonitor.class);
}

}
``` PrometheusMonitor 类是负责创建度量和诸如此类的事情的人。这里最重要的是它是由springboot管理的。

@Component
public class PrometheusMonitor {

    private MeterRegistry meterRegistry;

    public PrometheusMonitor(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
    }
}

你可能注意到了 PrometheusMonitorCustomLogger 我需要一个额外的类,以便从非spring托管类获取bean/访问上下文。这就是 SpringContext 具有 static 方法来通过提供的类获取bean。

@Component
public class SpringContext implements ApplicationContextAware {

    private static ApplicationContext context;

    public static <T extends Object> T getBean(Class<T> beanClass) {
        return context.getBean(beanClass);
    }

    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        SpringContext.context = context;
    }
}

所以在运行应用程序时,所有这些都可以正常工作。我保证装 SpringContext 先上课,所以每次一次 CustomLogger 得到示例化它只是工作。
但最大的问题来了:在单元测试我的应用程序时,这是不起作用的。我尝试了很多事情,我看到了一些可能对我有帮助但我正在努力避免的解决方案(例如使用powermockito)。Lombok山正在处理 @CustomLog 任何之前的注解 @Before 我添加到测试类的方法。一次 getBean() 方法调用时,我得到一个异常原因 contextnull .
我想如果我能强迫他们 SpringContext 在Lombok山变魔术之前上膛,但我不确定这是可能的。非常感谢您花时间阅读本文。我能提供的更多信息请告诉我。

svdrlsy4

svdrlsy41#

注意:像平常一样登录到slf4j,并在slf4j框架中注册一个额外的处理程序,这样slf4j就可以将任何日志转发给您(除了其他处理程序之外,比如生成日志文件的处理程序),这样就可以更好地满足您的自定义日志记录需求。
lombok正在处理@customlog
生成的日志字段是静态的。如果注解有任何帮助,您需要 @BeforeClass ,但这可能也不及时。Lombok山的魔法在这里似乎不相关。看看德隆博克告诉你Lombok湖在做什么:它只是。。静态字段,在声明时初始化。

rta7y2nd

rta7y2nd2#

我设法解决了这个问题 CustomLogger 作品。这意味着 monitor 字段以及记录器,您可以在第一次使用它时执行此操作。例如。:

public class CustomLogger {

    private org.slf4j.Logger logger;
    private Monitor monitor;

    public CustomLogger(String className) {
        this.logger = org.slf4j.LoggerFactory.getLogger(className);
    }

    public void info(String message) {
        this.logger.info(message);
    }

    public void error(String message) {
        this.logger.error(message);
        if (this.monitor == null) {
            this.monitor = SpringContext.getBean(PrometheusMonitor.class);
        }
        this.monitor.send(message);
    }
}

但毕竟我决定不采用这种方法,因为我认为这是最好的方法,不值得。

相关问题