Cela fait partie de mon job.xml
:
<job id="foo" job-repository="job-repository">
<step id="bar">
<tasklet transaction-manager="transaction-manager">
<chunk commit-interval="1"
reader="foo-reader" writer="foo-writer"
/>
</tasklet>
</step>
</job>
C'est le lecteur d'objet:
import org.springframework.batch.item.ItemReader;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component("foo-reader")
public final class MyReader implements ItemReader<MyData> {
@Override
public MyData read() throws Exception {
//...
}
@Value("#{jobParameters['fileName']}")
public void setFileName(final String name) {
//...
}
}
Voici ce que dit Spring Batch au moment de l'exécution:
Field or property 'jobParameters' cannot be found on object of
type 'org.springframework.beans.factory.config.BeanExpressionContext'
Quel est le problème ici? Où puis-je en savoir plus sur ces mécanismes dans Spring 3.0?
Comme il a été dit, votre lecteur doit avoir une "portée". Vous pouvez accomplir cela via l'annotation @Scope("step")
. Cela devrait fonctionner pour vous si vous ajoutez cette annotation à votre lecteur, comme suit:
import org.springframework.batch.item.ItemReader;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component("foo-reader")
@Scope("step")
public final class MyReader implements ItemReader<MyData> {
@Override
public MyData read() throws Exception {
//...
}
@Value("#{jobParameters['fileName']}")
public void setFileName(final String name) {
//...
}
}
Cette étendue n'est pas disponible par défaut, mais le sera si vous utilisez l'espace de noms XML batch
. Si vous ne l'êtes pas, l'ajout des éléments suivants à votre configuration Spring rendra la portée disponible, conformément à la documentation Spring Batch :
<bean class="org.springframework.batch.core.scope.StepScope" />
Si vous souhaitez définir votre instance ItemReader
et votre instance Step
dans une seule classe JavaConfig. Vous pouvez utiliser les @StepScope
et les @Value
annotations telles que:
@Configuration
public class ContributionCardBatchConfiguration {
private static final String WILL_BE_INJECTED = null;
@Bean
@StepScope
public FlatFileItemReader<ContributionCard> contributionCardReader(@Value("#{jobParameters['fileName']}")String contributionCardCsvFileName){
....
}
@Bean
Step ingestContributionCardStep(ItemReader<ContributionCard> reader){
return stepBuilderFactory.get("ingestContributionCardStep")
.<ContributionCard, ContributionCard>chunk(1)
.reader(contributionCardReader(WILL_BE_INJECTED))
.writer(contributionCardWriter())
.build();
}
}
L'astuce consiste à transmettre une valeur null à l'itemReader puisqu'il sera injecté via l'annotation @Value("#{jobParameters['fileName']}")
.
Merci à Tobias Flohre pour son article: Spring Batch 2.2 - JavaConfig, partie 2: JobParameters, ExecutionContext et StepScope
Pour pouvoir utiliser les paramètres jobParameters, je pense que vous devez définir votre lecteur comme une "étape" de la portée, mais je ne suis pas sûr que vous puissiez le faire en utilisant des annotations.
En utilisant xml-config, cela ressemblerait à ceci:
<bean id="foo-readers" scope="step"
class="...MyReader">
<property name="fileName" value="#{jobExecutionContext['fileName']}" />
</bean>
Voir plus loin le documentation Spring Batch .
Peut-être que cela fonctionne en utilisant @Scope
et définissant l’étendue de l’étape dans votre configuration xml:
<bean class="org.springframework.batch.core.scope.StepScope" />
Assez tard, mais vous pouvez aussi le faire en annotant une méthode @BeforeStep:
@BeforeStep
public void beforeStep(final StepExecution stepExecution) {
JobParameters parameters = stepExecution.getJobExecution().getJobParameters();
//use your parameters
}
Complétez avec un exemple supplémentaire, vous pouvez accéder à tous les paramètres de travail de la classe JavaConfig:
@Bean
@StepScope
public ItemStreamReader<GenericMessage> reader(@Value("#{jobParameters}") Map<String,Object> jobParameters){
....
}
Lors de l'exécution du travail, nous devons transmettre les paramètres du travail comme suit:
JobParameters jobParameters= new JobParametersBuilder().addString("file.name", "filename.txt").toJobParameters();
JobExecution execution = jobLauncher.run(job, jobParameters);
en utilisant le langage d'expression, nous pouvons importer la valeur comme suit:
#{jobParameters['file.name']}