【问题标题】:Parameter 0 of constructor in com.project.api.graphql.service.GraphQLService required a bean of type 'java.lang.String' that could not be foundcom.project.api.graphql.service.GraphQLService 中构造函数的参数 0 需要一个找不到的“java.lang.String”类型的 bean
【发布时间】:2021-02-02 15:45:10
【问题描述】:

我是 Spring Boot 新手,我想知道这个错误消息。

我正在尝试创建一个 GraphQL 类以连接到各种 GraphQL 配置,并且我想将一个值传递给构造函数(最终用于我的类路径):

public class ArticleResource {

    @Autowired
    GraphQLService graphQLService = new GraphQLService("classpath:articles.graphql");
    ... other code
}

public class GraphQLService {

    public GraphQLService(String value) {
        System.out.println(value);
    }
    ... other code with @Autowired & @PostConstruct annotations
}

我正在使用一个如何将 GraphQL 连接到 Spring Boot 的示例,并且我有几个地方使用了注解 @Autowired 以及 @PostConstruct。我觉得其中之一导致了我所看到的问题。

完整的错误如下:

Description:

Parameter 0 of constructor in com.project.api.graphql.service.GraphQLService required a bean of type 'java.lang.String' that could not be found.

The injection point has the following annotations:
    - @org.springframework.beans.factory.annotation.Autowired(required=true)


Action:

Consider defining a bean of type 'java.lang.String' in your configuration.

我将如何解决这个问题?我不能使用带有 Autowired 或 PostConstruct 注释的自定义构造函数吗?

【问题讨论】:

  • 似乎GraphQLService 没有其他构造函数,因此它将尝试调用该构造函数。而且由于您可能没有在任何地方定义String bean,因此您会收到错误消息。考虑定义无参数构造函数或定义String 类型的bean。这完全取决于您想要达到的目标。你也可以从你的属性文件中注入这个值,它实际上会更有意义。在这种情况下,您也滥用了自动装配,因为您正在使用 new 关键字创建实例。

标签: java spring spring-boot graphql


【解决方案1】:

就像评论中已经提到的 michalk 一样,您在 ArticleResource 中滥用了依赖注入 - 我强烈建议您通读 spring 的文档 here

基本上就是这样:你试图满足的依赖关系,在这种情况下GraphQLService 有一个带有一个字符串类型参数的构造函数。 Spring 将尝试注入它,但由于您在项目中没有定义 String 类型的 @Bean,因此它将失败并显示您提供的错误消息。

在您的情况下更有意义的是定义一个 @Configuration 类并从例如 application.properties 注入字符串值,如下所示:

@Configuration
public class GraphQLConfig {

    @Bean
    public GraphQLService graphQLService(@Value("${classpath.value}") String valueReadFromAppProperties) {
        return new GraphQLService(valueReadFromAppProperties);
    }
}

然后将以下内容添加到您的 application.properties 文件中:

classpath.value=classpath:articles.graphql

最后在 ArticleResource 中注入服务实例时:

public class ArticleResource {

    @Autowired
    GraphQLService graphQLService;
    ... other code
}

虽然可以通过使用构造函数注入而不是字段注入来改进:

public class ArticleResource {

    private GraphQLService graphQLService;

    public ArticleResource(GraphQLService graphQLService) {
        this.graphQLService = graphQLService;
    }
}

【讨论】:

  • 我可能想要做一些不同的事情,因为这个属性最终将是动态的,但感谢您的解释!这解释了我做错了什么。
  • 很高兴我能以某种方式提供帮助。也许试试这个SO entry 来弄清楚如何处理动态属性?
【解决方案2】:

首先是一些关于依赖注入的信息。如果您使用 Spring DI(依赖注入),则永远不要使用 new 关键字来创建“bean”依赖项的实例。让 Spring 为您处理。 另一个建议是使用有用的名称。 “价值”这个名字不好,因为价值可以是一切。为所有内容命名,使其具有有意义的名称。

您提供的代码示例不完整。您的 GraphQLService 类中可能有一个 @Service 注释。因为那个 Spring 试图在启动时启动 te 服务 bean。因为您在该类的构造函数中定义了一个 String,所以 Spring 尝试自动装配该依赖项。一个简单的字符串不是一个已知的 bean,因为你得到了错误。

请阅读 Spring 文档这是如何工作的。也许还可以查看spring-data,阅读文档并查看一些示例。这让您可以很好地了解 Spring 如何解决此类问题。

【讨论】:

    猜你喜欢
    • 2019-03-21
    • 2018-12-06
    • 2019-10-20
    • 1970-01-01
    • 2020-02-23
    • 2020-08-26
    • 2023-02-05
    • 1970-01-01
    • 2021-12-10
    相关资源
    最近更新 更多