Mis*_*bon 4 spring spring-boot
我在这里找到了很多关于使用@Autowired和非空构造函数的信息.但我甚至无法解决我目前的问题.
我有一个日志记录界面.我正在记录数据库中的每个条目.出于这个原因,我必须知道类名,哪个类使用记录器.
我的第一个想法:创建一个Logger的新实现,它有一个非空的构造函数.因此,在创建此记录器的新实例时,您必须设置名称.
我的界面看起来像这样:
public interface Logger{
public void log(String name, String msg);
}
Run Code Online (Sandbox Code Playgroud)
其实现如下:
@Service
public class LoggerImpl implements Logger{
private String className;
LoggerImpl(String className){ this.className = className }
@Override
public void log(String name, String msg) { // print and save in the database }
}
Run Code Online (Sandbox Code Playgroud)
在我的应用程序的任何地方我都想使用这个记录器 - 接口.例如,在某些业务类中,我以这种方式使用Logger:
@Service
public class ServiceName {
private Logger logger;
@Autowired
public ServiceName(){
logger = new LoggerImpl("ServiceName");
}
public void someMethod(){
logger.log("name", "this is a log!");
}
}
Run Code Online (Sandbox Code Playgroud)
但我的应用程序告诉我,他没有数据库通信并抛出一个NullPointerException,同时保存数据库中的日志.在创建非空构造函数之前,此通信有效.所以我的猜测是,当我手动创建此LoggerImpl时,此对象不再位于spring应用程序上下文中.有什么想法要解决?谢谢.编辑:我正在使用Spring Boot,我没有任何XML文件.
我认为在这种情况下用 @Service 注释是不够的。Spring 将无法创建 LoggerImpl 的实例。
您必须告诉 Spring 如何创建实例。当使用 XML 配置时,你应该这样做
<bean id="loggerForX" class="LoggerImpl ">
<constructor-arg index="0" value="X" />
</bean>
Run Code Online (Sandbox Code Playgroud)
使用javaconfig时
@Configuration
public class LoggerConfiguration {
@Bean
public Logger loggerForX() {
return new LoggerImpl("X");
}
}
Run Code Online (Sandbox Code Playgroud)
然后您将能够@Autowire Logger 作为
@Autowire Logger loggerForX;
Run Code Online (Sandbox Code Playgroud)
如果这不起作用,请尝试自动装配loggerForX变量 ab
@Autowire @Qualifier("loggerForX") Logger loggerForX;
使用这种方法,您必须为每个需要记录器的类创建单独的 bean。创建LoggerFactory为 bean 并注入它可能会更好LoggerFactory。LoggerFactory必须有方法来创建Logger。
@Service
class LoggerFactory {
public Logger loggerFor(String name) {
return new LoggerImpl(name);
}
}
Run Code Online (Sandbox Code Playgroud)
LoggerFactory有默认构造函数,可以轻松地出现在@Autowired您想要的任何地方。
您可能想看一下新的InjectionPoint
@Configuration
public class LoggerConfig {
@Bean
@Scope("prototype")
public Logger logger(InjectionPoint injectionPoint) {
//this is the class where the logger will be used
Class<?> theClassYouAreLookingFor = injectionPoint.getMember().getDeclaringClass();
return findOrCreateYourLogger(theClassYouAreLookingFor);
}
}
Run Code Online (Sandbox Code Playgroud)
要Logger像正常使用任何其他Bean一样使用它.
| 归档时间: |
|
| 查看次数: |
2594 次 |
| 最近记录: |