Зависимости некоторых компонентов в контексте приложения образуют цикл в весенней партии

#java #spring #spring-boot #spring-batch

#Ява #весна #пружинный ботинок #пружинная партия

Вопрос:

Я работаю над простым пакетным приложением Spring, и когда я закончил его настройку, я обнаружил эту проблему:

Зависимости некоторых компонентов в контексте приложения образуют цикл:

jobRestController, определенный в файле [/home/yassine/Downloads/demo/target/classes/com/example/demo/JobRestController.class] springBatchConfig, определенный в файле [/home/yassine/Downloads/demo/target/classes/com/example/demo/SpringBatchConfig.class]

Экшен:

Полагаться на циклические ссылки не рекомендуется, и по умолчанию они запрещены. Обновите приложение, чтобы удалить цикл зависимостей между компонентами. В крайнем случае, возможно, удастся автоматически прервать цикл, установив spring.main.allow-circular-ссылки на true.

Реализация двух классов:

SpringBatchConfig:

 import lombok.AllArgsConstructor; import org.springframework.batch.core.Job; import org.springframework.batch.core.Step; import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; import org.springframework.batch.item.ItemProcessor; import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemWriter; import org.springframework.batch.item.file.FlatFileItemReader; import org.springframework.batch.item.file.LineMapper; import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper; import org.springframework.batch.item.file.mapping.DefaultLineMapper; import org.springframework.batch.item.file.transform.DelimitedLineTokenizer; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.Resource;  @Configuration @EnableBatchProcessing @AllArgsConstructor public class SpringBatchConfig {   private JobBuilderFactory jobBuilderFactory;  private StepBuilderFactory stepBuilderFactory;  private ItemReaderlt;BankTransactiongt; bankTransactionItemReader;  private ItemProcessorlt;BankTransaction, BankTransactiongt; bankTransactionItemProcessor;  private ItemWriterlt;BankTransactiongt; bankTransactionItemWriter;   @Bean  public Job bankJob() {  Step step1 = stepBuilderFactory.get("step-load-data")  .lt;BankTransaction, BankTransactiongt;chunk(100)  .reader(bankTransactionItemReader)  .processor(bankTransactionItemProcessor)  .writer(bankTransactionItemWriter)  .build();  return jobBuilderFactory.get("bank-data-loader-job")  .start(step1)  .build();  }   @Bean  public FlatFileItemReaderlt;BankTransactiongt; flatFileItemReader(@Value("${inputFile}") Resource inputFile) {  FlatFileItemReaderlt;BankTransactiongt; flatFileItemReader = new FlatFileItemReaderlt;gt;();  flatFileItemReader.setName("CSV-READER");  flatFileItemReader.setLinesToSkip(1);  flatFileItemReader.setResource(inputFile);  flatFileItemReader.setLineMapper(lineMapper());  return flatFileItemReader;  }   @Bean  public LineMapperlt;BankTransactiongt; lineMapper() {  DefaultLineMapperlt;BankTransactiongt; lineMapper = new DefaultLineMapperlt;gt;();  DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer();  lineTokenizer.setDelimiter(",");  lineTokenizer.setStrict(false);  lineTokenizer.setNames("id", "accountID", "strTransactionDate", "transactionType", "amount");  lineMapper.setLineTokenizer(lineTokenizer);  BeanWrapperFieldSetMapperlt;BankTransactiongt; fieldSetMapper = new BeanWrapperFieldSetMapperlt;gt;();  fieldSetMapper.setTargetType(BankTransaction.class);  lineMapper.setFieldSetMapper(fieldSetMapper);  return lineMapper;  } }  

JobRestController:

 import lombok.AllArgsConstructor; import org.springframework.batch.core.*; import org.springframework.batch.core.launch.JobLauncher; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;  import java.util.HashMap; import java.util.Map;  @RestController @AllArgsConstructor public class JobRestController {   private JobLauncher jobLauncher;  private Job job;   @GetMapping("/startJob")  public BatchStatus load() throws Exception {  Maplt;String, JobParametergt; parameters = new HashMaplt;gt;();  parameters.put("time", new JobParameter(System.currentTimeMillis()));  JobParameters jobParameters = new JobParameters(parameters);  JobExecution jobExecution = jobLauncher.run(job, jobParameters);  while (jobExecution.isRunning()) {  System.out.println(".....");  }  return jobExecution.getStatus();  } }  

pom.xml:

 lt;?xml version="1.0" encoding="UTF-8"?gt; lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"gt;  lt;modelVersiongt;4.0.0lt;/modelVersiongt;  lt;parentgt;  lt;groupIdgt;org.springframework.bootlt;/groupIdgt;  lt;artifactIdgt;spring-boot-starter-parentlt;/artifactIdgt;  lt;versiongt;2.6.1lt;/versiongt;  lt;relativePath/gt; lt;!-- lookup parent from repository --gt;  lt;/parentgt;  lt;groupIdgt;com.examplelt;/groupIdgt;  lt;artifactIdgt;demolt;/artifactIdgt;  lt;versiongt;0.0.1-SNAPSHOTlt;/versiongt;  lt;namegt;demolt;/namegt;  lt;descriptiongt;demolt;/descriptiongt;  lt;propertiesgt;  lt;java.versiongt;11lt;/java.versiongt;  lt;/propertiesgt;  lt;dependenciesgt;  lt;dependencygt;  lt;groupIdgt;org.springframework.bootlt;/groupIdgt;  lt;artifactIdgt;spring-boot-starter-batchlt;/artifactIdgt;  lt;/dependencygt;  lt;dependencygt;  lt;groupIdgt;org.springframework.bootlt;/groupIdgt;  lt;artifactIdgt;spring-boot-starter-data-jpalt;/artifactIdgt;  lt;/dependencygt;  lt;dependencygt;  lt;groupIdgt;org.springframework.bootlt;/groupIdgt;  lt;artifactIdgt;spring-boot-starter-weblt;/artifactIdgt;  lt;/dependencygt;   lt;dependencygt;  lt;groupIdgt;org.springframework.bootlt;/groupIdgt;  lt;artifactIdgt;spring-boot-devtoolslt;/artifactIdgt;  lt;scopegt;runtimelt;/scopegt;  lt;optionalgt;truelt;/optionalgt;  lt;/dependencygt;  lt;dependencygt;  lt;groupIdgt;com.h2databaselt;/groupIdgt;  lt;artifactIdgt;h2lt;/artifactIdgt;  lt;scopegt;runtimelt;/scopegt;  lt;/dependencygt;  lt;dependencygt;  lt;groupIdgt;org.projectlomboklt;/groupIdgt;  lt;artifactIdgt;lomboklt;/artifactIdgt;  lt;optionalgt;truelt;/optionalgt;  lt;/dependencygt;  lt;dependencygt;  lt;groupIdgt;org.springframework.bootlt;/groupIdgt;  lt;artifactIdgt;spring-boot-starter-testlt;/artifactIdgt;  lt;scopegt;testlt;/scopegt;  lt;/dependencygt;  lt;dependencygt;  lt;groupIdgt;org.springframework.batchlt;/groupIdgt;  lt;artifactIdgt;spring-batch-testlt;/artifactIdgt;  lt;scopegt;testlt;/scopegt;  lt;/dependencygt;  lt;/dependenciesgt;   lt;buildgt;  lt;pluginsgt;  lt;plugingt;  lt;groupIdgt;org.springframework.bootlt;/groupIdgt;  lt;artifactIdgt;spring-boot-maven-pluginlt;/artifactIdgt;  lt;configurationgt;  lt;excludesgt;  lt;excludegt;  lt;groupIdgt;org.projectlomboklt;/groupIdgt;  lt;artifactIdgt;lomboklt;/artifactIdgt;  lt;/excludegt;  lt;/excludesgt;  lt;/configurationgt;  lt;/plugingt;  lt;/pluginsgt;  lt;/buildgt;  lt;/projectgt;  

Я не смог это исправить, и я не нашел подобной проблемы в StackOverflow. Заранее спасибо

Комментарии:

1. Можете ли вы поделиться своим pom.xml контентом или build.gradle контентом?

2. @chaitanyaguruprasad Я только что поделился этим, спасибо

3. Также, пожалуйста, опубликуйте свое сообщение об ошибке

4. @chaitanyaguruprasad да, я тоже опубликовал это в первой части, Зависимости некоторых компонентов в контексте приложения образуют цикл

Ответ №1:

сегодня у меня была та же проблема, и я решаю ее с помощью следующих шагов:

  1. вы должны создать ItemWriter,компоненты ItemProcessor
  2. объявите компонент задания в другом классе конфигурации

конфигурация весеннего пакета

 package com.example.demo.config;  import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.List;   import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; import org.springframework.batch.item.ItemProcessor; import org.springframework.batch.item.ItemWriter; import org.springframework.batch.item.file.FlatFileItemReader; import org.springframework.batch.item.file.LineMapper; import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper; import org.springframework.batch.item.file.mapping.DefaultLineMapper; import org.springframework.batch.item.file.transform.DelimitedLineTokenizer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.Resource;  import com.example.demo.dao.Person; import com.example.demo.dao.PersonRepository;  import lombok.RequiredArgsConstructor;  @Configuration @EnableBatchProcessing @RequiredArgsConstructor public class SpringBatchConfig {    @Bean  public FlatFileItemReaderlt;Persongt; getItemReader(@Value("${filePath}") Resource resource){  FlatFileItemReaderlt;Persongt; itemReader = new FlatFileItemReaderlt;Persongt;();  itemReader.setName("CSV-READER");  itemReader.setLinesToSkip(1);  itemReader.setResource(resource);  itemReader.setLineMapper(PersonLineMapper());  return itemReader;  }    @Bean  public LineMapperlt;Persongt; PersonLineMapper(){  DefaultLineMapperlt;Persongt; lineMapper = new DefaultLineMapperlt;Persongt;();  DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer();  lineTokenizer.setStrict(false);  lineTokenizer.setDelimiter(";");  lineTokenizer.setNames("id","fName","lName","strBirthDate","gender","dispo");  lineMapper.setLineTokenizer(lineTokenizer);  BeanWrapperFieldSetMapperlt;Persongt; fieldSetMapper = new BeanWrapperFieldSetMapperlt;Persongt;();  fieldSetMapper.setTargetType(Person.class);  lineMapper.setFieldSetMapper(fieldSetMapper);  return lineMapper;  }    @Bean  public ItemProcessorlt;Person, Persongt; getItemProcessor(){  return new ItemProcessorlt;Person, Persongt;() {  private DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");  @Override  public Person process(Person item) throws Exception {  item.setBirthDate(dateFormat.parse(item.getStrBirthDate()));  return item;  }  };  }    @Bean  public ItemWriterlt;Persongt; getItemWriter() {  return new ItemWriterlt;Persongt;() {  @Autowired   private PersonRepository personRepository;  @Override  public void write(Listlt;? extends Persongt; items) throws Exception {  personRepository.saveAll(items);    }  };  }  }  

Конфигурация задания

 package com.example.demo.config;  import org.springframework.batch.core.Job; import org.springframework.batch.core.Step; import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; import org.springframework.batch.item.ItemProcessor; import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemWriter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;  import com.example.demo.dao.Person;  import lombok.RequiredArgsConstructor;  @Configuration @RequiredArgsConstructor public class JobConfig {  private final JobBuilderFactory jobBuilderFactory;  private final StepBuilderFactory stepBuilderFactory;  private final ItemReaderlt;Persongt; personItemReader;  private final ItemWriterlt;Persongt; peronItemWriter;  private final ItemProcessorlt;Person, Persongt; personItemProcessor;    @Bean  public Job personJob() {  Step step1 = this.stepBuilderFactory.get("step-load-data")  .lt;Person,Persongt;chunk(100)  .writer(peronItemWriter)  .reader(personItemReader)  .processor(personItemProcessor)  .build();    return this.jobBuilderFactory.get("person-data-loader-job")  .start(step1)  .build();  }  }  

контроллер отдыха для запуска задания

 package com.example.demo.web;  import java.util.HashMap; import java.util.Map;  import org.springframework.batch.core.BatchStatus; import org.springframework.batch.core.Job; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobParameter; import org.springframework.batch.core.JobParameters; import org.springframework.batch.core.launch.JobLauncher; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;  import lombok.RequiredArgsConstructor;  @RestController @RequiredArgsConstructor public class PersonRestController {    private final JobLauncher jobLauncher;  private final Job job;    @GetMapping("/startBatch")  public BatchStatus load() throws Exception{  Maplt;String, JobParametergt; parameters = new HashMaplt;gt;();  parameters.put("time", new JobParameter(System.currentTimeMillis()));  JobParameters jobParameters = new JobParameters(parameters);  JobExecution jobExecution = jobLauncher.run(job, jobParameters);  while(jobExecution.isRunning()) {  System.out.println("....");  }  return jobExecution.getStatus();  }       }