我有以下背景:
@Configuration
@ComponentScan
public class MyContext {
@Bean
public Logger getLogger() {
return LoggerFactory.getLogger(MyContext.class);
}
@Bean
@Autowired
public RequestSpecification getRequestSpecification(RestServiceImpl restService) {
return restService.getService();
}
}
我的服务内部有@Autowired
字段(Logger):
@Service
public class RestServiceImpl {
@Autowired
Logger logger;
}
现在问题来了。当我尝试在其他服务中重用我的RequestSpecification
时:
@Service
public class RequestWrapperForMyEndpoint {
@Value("${rest.service.url}")
private String SERVICE_URL;
@Autowired
private RequestSpecification restService;
}
我遇到了NullPointerException
。因为Logger
没有注入RestServiceImpl
类。
是什么原因?
答案 0 :(得分:3)
我对你的具体问题的简单回答是:不要注射记录器。
@Service
public class RestServiceImpl {
private static Logger logger = LoggerFactory.getLogger(RestServiceImpl.class);
}
参数#1:无论你在一个类中记录什么,都应该使用该类的记录器。您不应该使用从MyContext初始化的记录器在RestServiceImpl中进行日志记录。减少记录器的数量是没有意义的。每个类应该有一个记录器,它不会影响你的性能,因为创建记录器非常便宜。
参数#2:实例化记录器的价格并不像自动装配bean那么便宜。自动装配/并且可能在其间具有自动生成的代理bean非常昂贵。
论据#3:有人可能会说,自动装配一切都是好的设计。然后你仍然可以争辩 - 是的,除了不依赖任何东西的物体之外的一切。记录器就是其中一个例外。根据定义,它不依赖于其他任何东西。
抱歉 - 但我对您的实际自动装配问题没有任何好处。
答案 1 :(得分:0)
这可能是一个评论,但由于我没有足够的分数,我只能发表答案。我们走了:
因此,此代码应该有效,这就是应该如何进行自动装配。
虽然自动装配记录器没有意义(正如Mick所解释的那样),因为每个日志条目都将链接到MyContext,您将无法分辨它实际来自哪里(在调试时没有帮助),是可能的解决方案对于自动装配问题:
LoggerFactory.getLogger(MyContext.class)
的返回值是否首先不为空。