在 Spring 启动的登录中的自定义评估器中注入依赖项



我正在编写一个自定义计算器,我想在其中自动连接另一个 bean。我无法这样做,因为评估器由记录器初始化,而 bean 由 spring 上下文初始化。下面是我的代码示例:

在倒数弹簧中.xml:

<appender name="myAppender" class="ch.qos.logback.classic.net.SMTPAppender">
<evaluator class="com.package.CustomEvaluator">
<marker>FATAL</marker>
<interval>1000000</interval>
</evaluator>
</appender>

我的自定义评估器:

@Slf4j
@Component
public class CustomEvaluator extends OnMarkerEvaluator {
@Autowired
private MyService myService;
@Override
public boolean evaluate(ILoggingEvent event) throws EvaluationException {
\logic goes here
}
}

我得到我的服务的对象总是为空(这是预期的(。有什么解决方法吗?

它认为这是不可能的,因为作为内部回传抽象的评估器不是由 spring 管理/初始化的,所以显然 spring 不能自动将任何东西连接到评估器中。

另请注意,该 logback 甚至在应用程序上下文启动之前就已初始化。

当然,您可以为应用程序上下文提供一些全局持有者类,并在 main 方法中为其设置上下文,然后在此评估器中获取对它的引用,如下所示:

public class ApplicationContextHolder {
private static ApplicationContext context;
// call it in main() method 
public static void setContext(ApplicationContext ctx) {context = ctx;}
public static ApplicationContext getContext() {return context;} 
}
class CustomEvaluator extends OnMarkerEvaluator {
public boolean evaluate(ILoggingEvent event) throws EvaluationException {
ApplicationContext ctx = ApplicationContextHolder.getContext();
if(ctx == null) {return false;} // not yet initialized / accessible
MyService myService = ctx.getBean(MyService.class);
}
}

但总而言之,我相信这是一个非常丑陋的解决方案。

作为建议,我认为您应该考虑重构逻辑,以便决定是否根据日志记录事件发送电子邮件将在应用程序中做出(我假设,这是 Spring 引导驱动的,因此您可以访问MyService

给定当前的实现:

public foo() {
LOGGER.info("This should be sent by email");
}

我建议应用程序的一部分:

@Component
public class MyLogic {
@Autowired MyService myService;
public void foo() {
if(myService.shouldSend()) {
LOGGER.info("This should be sent by email");
}
}
}

最新更新