自动装配的spring bean到自定义slf4j appender

时间:2014-04-07 14:51:31

标签: java spring

使用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 appender:

@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:我的log4j.properties文件:

 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

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

这是因为log4j在Spring之前被引导。

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

log4j - Accessing spring bean from logging appender class - Stack Overflow