使用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
答案 0 :(得分:0)
之前已经讨论过这个想法,可能不是完全相同的配置,但有些类似。基本上,它是关于在log4j驱动的环境中使用Spring管理的东西。并不容易做到,因为log4j的东西是在Spring之前初始化的。 请参阅here关于类似主题的其他讨论。
答案 1 :(得分:0)
这是因为log4j在Spring之前被引导。
以下答案可能有助于为该问题提供可能的解决方案:
log4j - Accessing spring bean from logging appender class - Stack Overflow