从 Tasklet 加载 Spring 集成上下文并访问原型 bean

Load Spring integration context and access prototype bean from a Tasklet

给定以下 spring 集成配置

...
import org.springframework.integration.ftp.session.FtpRemoteFileTemplate;

@Configuration
public class FtpConfig {

    @Bean
    @Scope("prototype")
    public FtpRemoteFileTemplate template(String param) {
        
        DefaultFtpSessionFactory sf = new DefaultFtpSessionFactory();
        
        // these parameters can be determined at runtime, that's why I need param
        sf.setHost("some host");
        sf.setUsername("some user");
        sf.setPassword("some pass");
        sf.setPort(21);
        
        return new FtpRemoteFileTemplate(sf);
    }

    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(FtpConfig.class);
        
        FtpRemoteFileTemplate template = ctx.getBean(FtpRemoteFileTemplate.class, "somevalue");

        String port = template.getSession().getHostPort();
        System.out.println(port);
        
        ctx.close();
    }
}

我可以 bootstrap 应用程序上下文并按类型获取 FtpRemoteFileTemplate bean 并将其传递给运行时参数 "somevalue".
我希望能够使用 CommandLineJobRunner 实用程序在我 运行 的 Spring 批处理作业中加载此配置:

java org.springframework.batch.core.launch.support.CommandLineJobRunner mypackage.JobConfig jobname param=somevalue

这是我的工作配置:

@Configuration
@EnableBatchProcessing
public class JobConfig {
    
    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Autowired
    private StepBuilderFactory stepBuilderFactory;
    
    @Bean
    public Job jobname() {
        return this.jobBuilderFactory.get("jobname")
                    .start(downloadCsvFile())
                    .build();
    }

    @Bean
    public Step downloadCsvFile() {
        return this.stepBuilderFactory.get("downLoadFile")
                    .tasklet(ftpGetTasklet())
                    .build();
    }
    @Bean
    public FtpGetTasklet ftpGetTasklet() {
        return new FtpGetTasklet();
    }   
}

我的问题是如何从 FtpGetTasklet 加载和访问 FtpRemoteFileTemplate bean?

public class FtpGetTasklet implements Tasklet {

    @Override
    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
        
        String param = chunkContext.getStepContext().getStepExecution().getJobParameters().getString("param");
        System.out.println("FtpGetTasklet execute: " + param);
        
        // how to load and access the template as I do in FtpConfig's main method???
        //
        // AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(FtpConfig.class);
        // FtpRemoteFileTemplate template = ctx.getBean(FtpRemoteFileTemplate.class, param);

        return RepeatStatus.FINISHED;
    }
}

不清楚你的整个应用程序是什么,但我会这样做:

@Configuration
@Import(FtpConfig.class)
@EnableBatchProcessing
public class JobConfig {

public class FtpGetTasklet implements Tasklet {

     @Autowired
     BeanFactory beanFactory;

    ...
      public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
         FtpRemoteFileTemplate template =  this.beanFactory.getBean(FtpRemoteFileTemplate.class, param);
 }