Spring Boot-如何使用非默认构造函数@Autowired一个Bean?
我发现了很多关于@Autowired使用非空构造函数的信息。但我甚至无法解决我目前的问题 我有一个日志界面。我正在记录数据库中的每个条目。出于这个原因,对于我来说,知道类名很重要,哪个类使用记录器 我的第一个想法是:创建Logger的新实现,它有一个非空构造函数。因此,在创建此记录器的新实例时,必须设置名称 我的界面如下所示:Spring Boot-如何使用非默认构造函数@Autowired一个Bean?,spring,spring-boot,Spring,Spring Boot,我发现了很多关于@Autowired使用非空构造函数的信息。但我甚至无法解决我目前的问题 我有一个日志界面。我正在记录数据库中的每个条目。出于这个原因,对于我来说,知道类名很重要,哪个类使用记录器 我的第一个想法是:创建Logger的新实现,它有一个非空构造函数。因此,在创建此记录器的新实例时,必须设置名称 我的界面如下所示: public interface Logger{ public void log(String name, String msg); } @Service publ
public interface Logger{
public void log(String name, String msg);
}
@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 }
}
其实现如下所示:
public interface Logger{
public void log(String name, String msg);
}
@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 }
}
在我的应用程序的任何地方,我都想使用这个记录器接口。例如,在某些业务类中,我以以下方式使用记录器:
@Service
public class ServiceName {
private Logger logger;
@Autowired
public ServiceName(){
logger = new LoggerImpl("ServiceName");
}
public void someMethod(){
logger.log("name", "this is a log!");
}
}
但我的应用程序告诉我,他没有数据库通信,在数据库中保存日志时抛出一个
NullPointerException
。在创建非空构造函数之前,此通信有效。所以我的猜测是,当我手动创建这个LoggerImpl时,这个对象不再位于spring应用程序上下文中。有什么解决办法吗?多谢各位编辑:我正在使用Spring Boot,没有任何XML文件 我认为在这种情况下,用@Service注释是不够的。
Spring将无法创建LoggerImpl的实例
您必须告诉Spring如何创建实例。
使用XML配置时,您应该执行以下操作
<bean id="loggerForX" class="LoggerImpl ">
<constructor-arg index="0" value="X" />
</bean>
然后您将能够@Autowire Logger作为
@Autowire Logger loggerForX;
如果这不起作用,请尝试自动连线loggerForX
variable ab
@Autowire@Qualifier(“loggerForX”)记录器loggerForX代码>
使用这种方法,您必须为每个需要日志记录器的类创建单独的bean。最好将LoggerFactory
创建为bean,并注入LoggerFactory
LoggerFactory
必须具有创建记录器的方法
@Service
class LoggerFactory {
public Logger loggerFor(String name) {
return new LoggerImpl(name);
}
}
LoggerFactory
具有默认构造函数,可以方便地在任何地方进行@Autowired
。您可能需要查看新的
@配置
公共类LoggerConfig{
@豆子
@范围(“原型”)
公共记录器记录器(注入点注入点){
//这是将使用记录器的类
类化您正在查找的类=injectionPoint.getMember().getDeclaringClass();
返回Find或CreateYourLogger(您正在查找的类);
}
}
要使用记录器
只需像通常使用任何其他Bean一样注入它。您正在spring外部实例化记录器(Logger=new LoggerImpl(“ServiceName”);
)。为什么?首先我要感谢你花时间回答。@Configuration的使用将迫使我为每个类创建一个新Bean。以我目前的情况,我有超过15门课。所以我会手动创建少于15个bean。你说@Qualifier是什么意思?你能给我一个例子或一个链接吗?请看我更新的编辑(LoggerFactory)。我同意每次创建单独的Bean在您的情况下是没有意义的。有关限定符,请参见编辑到帖子。只需再添加两条注释。有很多登录框架。你真的需要你自己的吗?此外,记录器通常没有依赖项,不能直接从构造函数或静态工厂方法创建。在这种情况下,它不是由Spring管理的。没什么大不了的,因为通常没有必要去模仿。所以对静态工厂的依赖是很好的。听起来不错。但这并不能解决问题。当你仔细看的时候。那么很明显,为什么它不起作用。我刚刚创建了一个具有相同结果的变通方法。在新的LoggerFactory中,我还创建了一个新实例,即使不是在应用程序上下文中。但我需要自己做-(我喜欢slf4j记录器。但就我而言,我不能使用它。这对我来说并不清楚。当我使用@Autowired连接到记录器时,我在哪里设置了DeclaredType IP?我只得到接口记录器的名称。这不是我想知道的。@Missbonbonbon你是对的,对不起。我使用了错误的InjectionPoint方法。WithInjectionPoint.getMember()