Spring Boot-如何使用非默认构造函数@Autowired一个Bean?

Spring Boot-如何使用非默认构造函数@Autowired一个Bean?,spring,spring-boot,Spring,Spring Boot,我发现了很多关于@Autowired使用非空构造函数的信息。但我甚至无法解决我目前的问题 我有一个日志界面。我正在记录数据库中的每个条目。出于这个原因,对于我来说,知道类名很重要,哪个类使用记录器 我的第一个想法是:创建Logger的新实现,它有一个非空构造函数。因此,在创建此记录器的新实例时,必须设置名称 我的界面如下所示: public interface Logger{ public void log(String name, String msg); } @Service publ

我发现了很多关于@Autowired使用非空构造函数的信息。但我甚至无法解决我目前的问题

我有一个日志界面。我正在记录数据库中的每个条目。出于这个原因,对于我来说,知道类名很重要,哪个类使用记录器

我的第一个想法是:创建Logger的新实现,它有一个非空构造函数。因此,在创建此记录器的新实例时,必须设置名称

我的界面如下所示:

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方法。With
InjectionPoint.getMember()