自动将弹簧豆连接到自定义 slf4j 追加器



使用 AspectJ,我将服务注入到非托管域对象中:这是服务:

@Service
public class DomainServiceImpl implements DomainService { 
     public String getLoggerMessage(String prevMessage) {
            return String.format("Message from logger service:%s", prevMessage);
    }
}

这是域对象:

@Configurable(dependencyCheck = true)
public class DomainObject {
    private IAppenderService appenderService;
    @Autowired
    public void setAppenderService(IAppenderService appenderService) {
        this.appenderService = appenderService;
    }
    public IAppenderService getAppenderService() {
        return appenderService;
    }   
    public String formMessage(String message){      
        return appenderService.getLoggerMessage(message);
    }   
}

以下测试成功:

@Test
    public void testAppender(){
        DomainObject domainObject = new DomainObject();
        assertNotNull(domainObject.getAppenderService());
    }

如果我添加

System.out.println(new DomainObject().formMessage("test message"));

对于我在控制台中有预期字符串的任何控制器:"来自记录器服务的消息:测试消息"

然后我尝试将此服务用于自定义 slf4j 附加器:

@Configurable(dependencyCheck = true)
public class MyAppender extends AppenderSkeleton {  
    IAppenderService    appenderService;        
    @Autowired
    public void setAppenderService(IAppenderService appenderService) {
        this.appenderService = appenderService;
    }
    public IAppenderService getAppenderService() {
        return appenderService;
    }
    @Override
    public void close() {
    }
    @Override
    public boolean requiresLayout() {       
        return false;
    }
    @Override
    protected void append(LoggingEvent event) {     
        System.out.println(new DomainObject().formMessage(event.getMessage().toString()));
    }
}

但必须 NPE:

java.lang.NullPointerException
    at sbk.spring.testaopjc.domain.DomainObject.formMessage(DomainObject.java:19)
    at sbk.spring.testaopjc.appender.MyAppender.append(MyAppender.java:29)
    at org.apache.log4j.AppenderSkeleton.doAppend(AppenderSkeleton.java:251)

同时以下测试成功:

public void testAppendeSecond(){
        MyAppender appender = new MyAppender();
        assertNotNull(appender.getAppenderService());
    }

谁能解释为什么MyAppender在这种情况下表现不同?PS:我的日志4j属性文件:

 log4j.rootLogger=INFO, STDOUT
 log4j.appender.STDOUT=sbk.spring.testaopjc.appender.MyAppender
 log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
 log4j.appender.STDOUT.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%M:%L - %m%n

发生这种情况是因为 log4j 在 Spring 之前被引导。

以下答案可能有助于为该问题提供可能的解决方案:

log4j - 从日志记录追加器类访问 spring bean - 堆栈溢出

这个想法之前已经讨论过,也许不是完全相同的配置,但有些相似。基本上,它是关于在log4j驱动的环境中使用Spring管理的东西。而且不容易做到,因为log4j的东西是在Spring之前初始化的。请参阅此处有关类似主题的另一个讨论。

最新更新