为什么我得到异常 "Found ambiguous parameter type"? Spring 批量集成

Why do I get the exception "Found ambiguous parameter type"? Spring Batch Integration

我正在向 here 学习 Spring 批处理集成,我知道如何在收到消息时启动作业。现在,我想获取消息的名称和路径(这是一个文件)。以下是我的工作代码。但是,如果我取消注释 setFileParameterName 方法,则会出现以下异常:

java.lang.IllegalArgumentException: Found ambiguous parameter type [class java.lang.String] for method match: [public void com.example.batchprocessing.FileMessageToJobRequest.setFileParameterName(java.lang.String), public void com.example.batchprocessing.FileMessageToJobRequest.setJob(org.springframework.batch.core.Job)]

为什么会出现这个异常?该消息对我来说毫无意义。我传入了一个字符串,这两种方法有点混淆,但其中一个接受字符串,另一个接受工作?对此的任何帮助表示赞赏。

FileMessageToJobRequest.java

public class FileMessageToJobRequest {

private String filePathParameterName;
private Job job;
private String fileParameterName;

public void setFilePathParameterName(String filePathParameterName) {
    this.filePathParameterName = filePathParameterName;
}

public void setJob(Job job) {
    this.job = job;
}

//  public void setFileParameterName(String fileParameterName) {
//      this.fileParameterName = fileParameterName;
//  }

@Transformer
public JobLaunchRequest toRequest(Message<File> message) throws IOException {
    JobParametersBuilder jobParametersBuilder = new JobParametersBuilder();
//      jobParametersBuilder.addString(fileParameterName, message.getPayload().getName());
    jobParametersBuilder.addString(filePathParameterName, message.getPayload().getCanonicalPath());
    jobParametersBuilder.addDate("dummy", new Date()); // need to add at least one unique identifier so that it will run more than once
    return new JobLaunchRequest(job, jobParametersBuilder.toJobParameters());
}

}

BatchIntegrationConfiguration.java

@Configuration
@EnableIntegration
@EnableBatchProcessing
public class BatchIntegrationConfiguration {

@Autowired
private JobBuilderFactory jobBuilderFactory;

@Autowired
private StepBuilderFactory stepBuilderFactory;

@Autowired
private JobRepository jobRepository;

@Bean
public MessageChannel files() {
    return new DirectChannel();
}

@Bean
public FileMessageToJobRequest fileMessageToJobRequest() {
    FileMessageToJobRequest fileMessageToJobRequest = new FileMessageToJobRequest();
//      fileMessageToJobRequest.setFileParameterName("input.file.name")
    fileMessageToJobRequest.setFilePathParameterName("input.file.path");
    fileMessageToJobRequest.setJob(runBatchScriptJob());
    return fileMessageToJobRequest;
}

@Bean
public JobLaunchingGateway jobLaunchingGateway() {
    SimpleJobLauncher simpleJobLauncher = new SimpleJobLauncher();
    simpleJobLauncher.setJobRepository(jobRepository);
    simpleJobLauncher.setTaskExecutor(new SyncTaskExecutor());
    JobLaunchingGateway jobLaunchingGateway = new JobLaunchingGateway(simpleJobLauncher);

    return jobLaunchingGateway;
}

@Bean
public IntegrationFlow integrationFlow(JobLaunchingGateway jobLaunchingGateway) {
    return IntegrationFlows.from(Files.inboundAdapter(new File("./src/main/resources")).
            filter(new SimplePatternFileListFilter("simplebatchfile.bat")),
            c -> c.poller(Pollers.fixedRate(10000).maxMessagesPerPoll(1))).
            handle(fileMessageToJobRequest()).
            handle(jobLaunchingGateway).
            log(LoggingHandler.Level.WARN, "headers.id + ': ' + payload").
            get();
}

@Bean
public Job runBatchScriptJob() {
    return jobBuilderFactory.get("runBatchScriptJob")
            .listener(new JobCompletionNotificationListener())
            .start(runBatchScriptStep())
            .build();
}

@Bean
public Step runBatchScriptStep() {
    return stepBuilderFactory.get("runBatchScriptStep")
            .tasklet(runBatchScriptTasklet(null))
            .build();
}

@Bean
@StepScope
public Tasklet runBatchScriptTasklet(@Value("#{jobParameters['input.file.path']}") String filePath) {
    RunBatchScriptTasklet tasklet = new RunBatchScriptTasklet();
    tasklet.setFilePath(filePath);
    return tasklet;
}

}

StackTrace

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'integrationFlow' defined in class path resource [com/example/batchprocessing/BatchIntegrationConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.integration.dsl.IntegrationFlow]: Factory method 'integrationFlow' threw exception; nested exception is java.lang.IllegalArgumentException: Found ambiguous parameter type [class java.lang.String] for method match: [public void com.example.batchprocessing.FileMessageToJobRequest.setFileParameterName(java.lang.String), public void com.example.batchprocessing.FileMessageToJobRequest.setJob(org.springframework.batch.core.Job)]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:656) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:636) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean[=15=](AbstractBeanFactory.java:323) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:879) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878) ~[spring-context-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) [spring-boot-2.2.5.RELEASE.jar:2.2.5.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.2.5.RELEASE.jar:2.2.5.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-2.2.5.RELEASE.jar:2.2.5.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.2.5.RELEASE.jar:2.2.5.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) [spring-boot-2.2.5.RELEASE.jar:2.2.5.RELEASE]
    at com.example.batchprocessing.BatchProcessingApplication.main(BatchProcessingApplication.java:14) [classes/:na]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.integration.dsl.IntegrationFlow]: Factory method 'integrationFlow' threw exception; nested exception is java.lang.IllegalArgumentException: Found ambiguous parameter type [class java.lang.String] for method match: [public void com.example.batchprocessing.FileMessageToJobRequest.setFileParameterName(java.lang.String), public void com.example.batchprocessing.FileMessageToJobRequest.setJob(org.springframework.batch.core.Job)]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:651) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    ... 18 common frames omitted
Caused by: java.lang.IllegalArgumentException: Found ambiguous parameter type [class java.lang.String] for method match: [public void com.example.batchprocessing.FileMessageToJobRequest.setFileParameterName(java.lang.String), public void com.example.batchprocessing.FileMessageToJobRequest.setJob(org.springframework.batch.core.Job)]
    at org.springframework.util.Assert.isNull(Assert.java:176) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.integration.handler.support.MessagingMethodInvokerHelper.validateFallbackMethods(MessagingMethodInvokerHelper.java:755) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.integration.handler.support.MessagingMethodInvokerHelper.findHandlerMethodsForTarget(MessagingMethodInvokerHelper.java:740) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.integration.handler.support.MessagingMethodInvokerHelper.<init>(MessagingMethodInvokerHelper.java:294) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.integration.handler.support.MessagingMethodInvokerHelper.<init>(MessagingMethodInvokerHelper.java:231) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.integration.handler.support.MessagingMethodInvokerHelper.<init>(MessagingMethodInvokerHelper.java:225) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.integration.handler.MethodInvokingMessageProcessor.<init>(MethodInvokingMessageProcessor.java:62) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.integration.handler.ServiceActivatingHandler.<init>(ServiceActivatingHandler.java:39) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.integration.dsl.BaseIntegrationFlowDefinition.handle(BaseIntegrationFlowDefinition.java:960) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.integration.dsl.IntegrationFlowDefinition.handle(IntegrationFlowDefinition.java:510) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.integration.dsl.IntegrationFlowDefinition.handle(IntegrationFlowDefinition.java:65) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.integration.dsl.BaseIntegrationFlowDefinition.handle(BaseIntegrationFlowDefinition.java:939) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.integration.dsl.IntegrationFlowDefinition.handle(IntegrationFlowDefinition.java:503) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.integration.dsl.IntegrationFlowDefinition.handle(IntegrationFlowDefinition.java:65) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.integration.dsl.BaseIntegrationFlowDefinition.handle(BaseIntegrationFlowDefinition.java:926) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.integration.dsl.IntegrationFlowDefinition.handle(IntegrationFlowDefinition.java:498) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at com.example.batchprocessing.BatchIntegrationConfiguration.integrationFlow(BatchIntegrationConfiguration.java:78) ~[classes/:na]
    at com.example.batchprocessing.BatchIntegrationConfiguration$$EnhancerBySpringCGLIB$8a9f8a.CGLIB$integrationFlow(<generated>) ~[classes/:na]
    at com.example.batchprocessing.BatchIntegrationConfiguration$$EnhancerBySpringCGLIB$8a9f8a$$FastClassBySpringCGLIB$$b8a5aaf.invoke(<generated>) ~[classes/:na]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331) ~[spring-context-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at com.example.batchprocessing.BatchIntegrationConfiguration$$EnhancerBySpringCGLIB$8a9f8a.integrationFlow(<generated>) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_211]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_211]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_211]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_211]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    ... 19 common frames omitted

这个 handle(fileMessageToJobRequest()) 必须改为 transform(fileMessageToJobRequest()),因为你的 FileMessageToJobRequest 实际上是 @Transformerhandle() 不理解该注解,并试图找出在运行时执行的任何候选方法。

消息Found ambiguous parameter type表示有几个不同参数的方法可以作为消息处理的候选者。在这种情况下,我们需要更加具体。就像你的 @Transformer 是一个很好的标记,但它用错了地方 - handle() 用于 @ServiceActivator.