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

huangapple go评论81阅读模式
英文:

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

问题

我刚接触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注解的情况下使用自定义构造函数吗?

英文:

I am new to Spring Boot, and I am wondering about this error message.

I am trying to create a GraphQL class to connect to various GraphQL configurations, and I want to pass a value to the constructor (for my class path, ultimately):

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
}

I am using an example of how to connect GraphQL to Spring Boot, and I have several places where the annotation @Autowired is used as well as @PostConstruct. I feel like one of those is leading to the problem I am seeing.

The full error is as follows:

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.

How would I solve this? Am I not able to use a custom constructor with Autowired or PostConstruct annotations?

答案1

得分: 2

就像 michalk 在评论中已经提到的,你在 ArticleResource 中误用了依赖注入 - 我强烈鼓励你阅读一下 Spring 的文档 这里

基本上发生的是:你试图满足的依赖,也就是 GraphQLService,有一个带有一个类型为 String 的参数的构造函数。Spring 会尝试注入它,但由于在你的项目中没有定义类型为 String 的 @Bean,所以它会因为你提供的错误消息而失败。

在你的情况下,更合理的做法是定义一个 @Configuration 类,然后从例如 application.properties 文件中注入 String 值,就像这样:

@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;
    ... 其他代码
}

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

public class ArticleResource {

    private GraphQLService graphQLService;

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

Like michalk already mentioned in the comment, you are misusing dependency injection in your ArticleResource - I strongly encourage you to read through spring's documentation here.

Basically that is what happens: The dependency you are trying to satisfy, in this case GraphQLService has one constructor with one parameter of type String. Spring will try to inject it, but since nowhere in your project you defined @Bean of type String, it will fail with error message you provided.

What would make more sense in your case would be to define a @Configuration class and inject the String value from for example application.properties, like this:

@Configuration
public class GraphQLConfig {

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

and then add following to your application.properties file:

classpath.value=classpath:articles.graphql

And finally when injecting an instance of your service in ArticleResource:

public class ArticleResource {

    @Autowired
    GraphQLService graphQLService;
    ... other code
}

Although it could be improved by using constructor injection, instead of field injection:

public class ArticleResource {

    private GraphQLService graphQLService;

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

答案2

得分: 0

关于依赖注入的一些信息。如果您使用Spring DI(依赖注入),请不要使用new关键字来创建“bean”依赖的实例。让Spring来处理这个任务。

另一个建议是使用有意义的名称。名称“value”是不好的,因为“value”可以是任何东西。给所有东西起一个能表达其含义的名字。

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

请阅读Spring文档以了解这是如何工作的。也许还可以查阅spring-data,阅读文档并查看一些示例。这将为您提供一个很好的概述,说明了Spring是如何解决这种类型的问题的。

英文:

First some info about dependency injection. If you use Spring DI (Dependency Injection) never use the new keyword to create instances of your "bean" dependencies. Let handle Spring that for you.
Another advice is to use useful names. The name "value" is bad, because value can be everything. Name everything so that it has a meaningful name.

The code example you give is not complete. Probably you have a @Service annotation in your GraphQLService class. Because that Spring tries to initiate te service bean at startup time. Because you defined a String in the constructor of that class, Spring tries to autowire that dependency. A simple string is not a known bean and because that you get the error.

Please read the Spring documentation how this is working. Maybe also look to spring-data, read the documentation and look at some examples. That gives you a good overview how this kind of things are solved with Spring.

huangapple
  • 本文由 发表于 2020年10月20日 04:17:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/64434569.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定