【问题标题】:Parameter 0 of constructor in required a bean of type 'java.lang.String' that could not be found构造函数的参数 0 需要一个找不到的“java.lang.String”类型的 bean
【发布时间】:2019-03-21 08:24:30
【问题描述】:

我正在使用 Spring Boot 2.X 应用程序开发 Spring Batch,实际上它的现有代码是从 git 中签出的。在运行应用程序时,由于以下错误仅适用于我而失败,并且相同的代码适用于其他人。

s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'inputItemReader' defined in file [C:\Users\XYZ\git\main\batch\CBatchProcessing\target\classes\com\main\batchprocessing\batch\reader\InputItemReader.class]: Unsatisfied dependency expressed through **constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.lang.String' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations**: {}


Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2018-10-16 23:23:37.411 ERROR 2384 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

**Parameter 0 of constructor in com.main.batchprocessing.batch.reader.InputItemReader required a bean of type 'java.lang.String' that could not be found.**


Action:

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

我已经在下面检查了

  1. 所有 Spring 组件都正确地用 @Component、@Service、@Controller、@Repository 等注释...
  2. 还提供了@ComponentScan 和@EnableAutoCONfiguration。
  3. 尝试在声明中给出“java.lang.String”。

代码:

    import java.util.Map;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.batch.core.ExitStatus;
    import org.springframework.batch.core.StepExecution;
    import org.springframework.batch.core.StepExecutionListener;
    import org.springframework.batch.item.file.FlatFileItemReader;
    import org.springframework.batch.item.file.mapping.JsonLineMapper;
    import 
    org.springframework.batch.item.file.separator.JsonRecordSeparatorPolicy;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.core.io.FileSystemResource;
    import org.springframework.stereotype.Component;

    @Component
    public class InputItemReader extends  FlatFileItemReader<Map<String, 
     Object>> implements StepExecutionListener {

    @Autowired
    private InputFileHeaderValidator inputFileHeaderValidator; 

    @Autowired
    private FileAuditService fileAuditService;

    private final Logger log = 
    LoggerFactory.getLogger(InputItemReader.class);

    private java.lang.String inputFilePath;

    public InputItemReader(String inputFilePath) {
        setLineMapper(new JsonLineMapper());
        setRecordSeparatorPolicy(new JsonRecordSeparatorPolicy());
        setResource(new FileSystemResource(inputFilePath));
        this.inputFilePath = inputFilePath;
    }
   }

【问题讨论】:

标签: java spring-boot spring-batch spring-annotations


【解决方案1】:

对我来说,这是因为使用了 lombok 的 @AllArgsConstructor 注解。我的代码是这样的:

@Service
@AllArgsConstructor
public class SampleService {

    @Value("${search.page.size}")
    private Integer pageSize;

    private final SampleRepository sampleRepository;

然后,我删除了@AllArgsConstructor 并添加了@RequiredArgsConstructor 注释。问题解决了。

@Service
@RequiredArgsConstructor
public class SampleService {

    @Value("${search.page.size}")
    private Integer pageSize;

    private final BatchRepository batchRepository;

【讨论】:

    【解决方案2】:

    我最近遇到了这个问题,结果发现我没有在我的项目的服务文件中添加“@Component”注释。效果是这个类没有被实例化为一个 spring bean。

    【讨论】:

      【解决方案3】:

      导入 lombok.RequiredArgsConstructor;

      导入 lombok.extern.slf4j.Slf4j;

      @Service
          @RequiredArgsConstructor
          @Transactional
          @Slf4j
          public class UserServiceImp implements UserService, UserDetailsService {
          ....
          }
      

      【讨论】:

        【解决方案4】:

        在我的例子中,用 lombok @NonNull 注释字段是造成问题的原因。

        【讨论】:

          【解决方案5】:

          即使按照上述解决方案,如果问题仍然存在,请检查您的导入语句。

          在我的情况下,这是 @service 注释的错误导入。

          【讨论】:

            【解决方案6】:

            我遇到了同样的错误,但错误是由 Feign Client 生成的。如果您在使用 feign 客户端时遇到此错误,则必须在主类中添加 @EnableFeignClients

            @SpringCloudApplication
            @EnableFeignClients
            public class Application {
            ...
            }
            

            【讨论】:

              【解决方案7】:

              我遇到了同样的问题,通过从我的模型类中删除构造函数得到了解决。在下面添加示例 sn-p:

              Map<String, ServiceDefinition> serviceDefinitionMapper = new HashMap<>();
                  A def;
                  B serviceCharacter;
              
                  @Autowired
                  public Scan(Map<String, ServiceDefinition> serviceDefinitionMapper, A def,
                          B serviceCharacter) {
                      super();
                      this.serviceDefinitionMapper = serviceDefinitionMapper;
                      this.def = def;
                      this.serviceCharacter = serviceCharacter;
                  }
              

              请注意:不要在模型类中保留任何 Constructor/@AllArgsConstructor,除非非常需要贴花。

              【讨论】:

                【解决方案8】:

                我也遇到了同样的问题,对我来说,以下解决方案效果很好:

                我通过导入 import lombok.AllArgsConstructor 将我的班级注释为 @AllArgsConstructor

                我刚刚删除了这个注释,代码开始工作了。

                希望这可以帮助某人。

                【讨论】:

                  【解决方案9】:

                  我的问题是多余的@Autowired, 我最初使用@Autowired 添加了一个依赖项,最终将其注释掉,但是我忘记了注释注释,因此@Autowired 旁边的方法被认为是某种setter。

                  删除多余的注释后它工作正常。

                  【讨论】:

                    【解决方案10】:

                    在我的情况下,问题完全不同。

                    @SpringBootApplication
                    @EnableNeo4jRepositories("com.digital.api.repositories") // <-- This was non-existent.
                    public class Application {
                    
                        public static void main(String[] args) {
                            SpringApplication.run(Application.class, args);
                        }
                    }
                    

                    查看@EnableNeo4jRepositories 注解。定义的包不存在。 尝试定义该包,并注意存储库接口基于那里。 否则,Spring 将找不到它应该加载的存储库类!

                    【讨论】:

                      【解决方案11】:

                      确保您使用的是 spring-boot-starter-data-jpa

                      <dependency>
                         <groupId>org.springframework.boot</groupId>
                         <artifactId>spring-boot-starter-data-jpa</artifactId>
                      </dependency>
                      

                      【讨论】:

                      • 提供尽可能多的上下文总是好的。例如,这里您没有在 Maven 依赖项中指定版本。例如,您可以扩展 spring-boot bom 并声明如果不使用 boms 可能需要一个版本。这只是一个例子。如果可能的话,尝试至少提供一些上下文总是好的。请参阅此处stackoverflow.com/help/how-to-answer,特别是在“回答问题”副标题下
                      【解决方案12】:

                      我也有同样的错误:

                      ***************************
                      APPLICATION FAILED TO START
                      ***************************
                      
                      Description:
                      
                      Field repository in com.example.controller.CampaignController required a bean of type 'com.example.data.CustomerRepository' that could not be found.
                      
                      
                      Action:
                      
                      Consider defining a bean of type 'com.example.data.CustomerRepository' in your configuration.de here
                      

                      我通过在主类中添加@EnableMongoRepositories 注解解决了这个问题:

                      @SpringBootApplication
                      @EnableMongoRepositories(basePackageClasses = CustomerRepository.class)
                      public class CampaignAPI {
                      
                          public static void main(String[] args) {
                              SpringApplication.run(CampaignAPI.class, args);
                          }
                      }
                      

                      【讨论】:

                      • 好收获!这解决了我的问题。但是,像这样添加所有存储库会更好吗? basePackageClasses = Foo1Repository.class, Foo2Repository.class... ?
                      【解决方案13】:

                      在您的类中添加一个公共默认构造函数。例如。

                      public User() {
                      }
                      

                      【讨论】:

                      • 感谢您的分享。这帮助我解决了项目中的问题。我有点困惑。即使我能够使用自定义构造函数创建 bean,我的许多服务类也没有公共构造函数。但是我开始遇到一个服务类的问题,通过提供默认构造函数解决了这个问题。我正在从配置类创建 bean,其中参数值是从属性文件中获取的。
                      • 如果你使用 Lombok,你可以在类的顶部添加注解(@NoArgsConstructor)。
                      【解决方案14】:

                      由于您没有提供公共默认构造函数并且您添加了自己的非默认构造函数,因此实例化将失败。我建议您将输入文件路径定义为@Value("${inputFilePath}") 之类的属性。 如果您需要在 bean 中进一步初始化,请定义一个 void 方法并使用 @PostConstruct 对其进行注释并在其中进行初始化。

                      【讨论】:

                      【解决方案15】:

                      你定义了这样的东西:

                      @Component
                      public class InputItemReader{
                      
                         public InputItemReader(String input){
                           ...
                         }
                      }
                      

                      你的类的名字表明你的对象不是一个bean,只是一个简单的对象。您应该尝试以经典方式使用它:

                      new InputItemReader(myString);
                      

                      或者有一个静态方法来处理输入的字符串。

                      说明:Spring IoC 容器将尝试像这样实例化一个新的 InputItemReader 对象:

                      new InputItemReader( -- WHAT TO PUT HERE? --) 
                      

                      并且将无法调用您的构造函数,因为它不会知道您实际期望什么并输入字符串。

                      更新: 您的问题可以通过删除 @Component 注释并在配置中定义 bean 来解决,如下所示:

                      @Bean
                      public InputItemReader inputItemReader(InputFileHeaderValidator inputFileHeaderValidator, FileAuditService fileAuditService){
                          InputItemReader inputItemReader = new InputItemReader("--HERE SHOULD BE ACTUAL PATH---");
                          // set the required service, a cleaner approach would be to send them via constructor
                          inputItemReader.setFilteAuditService(fileAuditService);
                          inputItemReader.setInputFileHeaderValidator(inputFileHeaderValidator);
                          return inputItemReader;
                      }
                      

                      【讨论】:

                      • 我理解你的意思,但是同样的代码正在为其他人工作而不为我工作..我真的不明白为什么会这样?我已经添加了代码,请您检查一次
                      • 应该如何接收 inputFilePath?你在运行前就知道这个值了吗?
                      猜你喜欢
                      • 2021-02-02
                      • 2018-12-06
                      • 2019-10-20
                      • 2023-02-05
                      • 2020-02-23
                      • 1970-01-01
                      • 2022-11-29
                      • 2020-08-26
                      • 2020-10-17
                      相关资源
                      最近更新 更多