Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring批处理集成—如何让远程执行JVM上的StepLocator能够看到作业外部的远程步骤?_Spring_Spring Integration_Spring Batch - Fatal编程技术网

Spring批处理集成—如何让远程执行JVM上的StepLocator能够看到作业外部的远程步骤?

Spring批处理集成—如何让远程执行JVM上的StepLocator能够看到作业外部的远程步骤?,spring,spring-integration,spring-batch,Spring,Spring Integration,Spring Batch,我已经为远程分区配置了我的作业,我正在通过kafka发送消息,从VM正在接收请求并尝试启动该步骤,但它找不到该步骤 我提供的beanFactory(applicationContext)似乎不包含远程执行步骤 我已经多次浏览了这个示例,但是我不知道如何为从属作业识别和设置正确的beanFactory 在应用程序初始化期间,从作业库加载ClasspathXmlApplicationContextsFactoryBean,其中包含所有spring批处理作业和远程从属步骤的XML。这个bean包含每个

我已经为远程分区配置了我的作业,我正在通过kafka发送消息,从VM正在接收请求并尝试启动该步骤,但它找不到该步骤

我提供的beanFactory(applicationContext)似乎不包含远程执行步骤

我已经多次浏览了这个示例,但是我不知道如何为从属作业识别和设置正确的beanFactory

在应用程序初始化期间,从作业库加载ClasspathXmlApplicationContextsFactoryBean,其中包含所有spring批处理作业和远程从属步骤的XML。这个bean包含每个XML文件的单独资源,包括从属文件(如预期的),并分配给applicationContext

@Bean
public ClasspathXmlApplicationContextsFactoryBean classpathXmlApplicationContextsFactoryBean () throws IOException
{
    String resourcePath = configPropertiesService
            .fetchPropertyValue(PropertyValueConstants.MXARCHIVE_SKELETON_LOCATION,
                    PropertyValueConstants.MXARCHIVE_SKELETON_LOCATION_DEFAULT)
            .getValue() + "*.xml";

    logger.trace("classpathXmlApplicationContextsFactoryBean()  :: {} ", resourcePath);
    Resource[] resources = applicationContext.getResources(resourcePath);

    ClasspathXmlApplicationContextsFactoryBean bean = new ClasspathXmlApplicationContextsFactoryBean ();
    bean.setApplicationContext(applicationContext);
    bean.setResources(resources);

    return bean;
}
@Bean
public BeanFactoryStepLocator stepLocator() throws Exception
{
    BeanFactoryStepLocator stepLocator = new BeanFactoryStepLocator ();

/* applicationContext is autowired in the postconstruct - what we do here doesn't matter
    stepLocator.setBeanFactory(applicationContext); // TODO: Find the right factory
    */
    return stepLocator;
};

// EDIT: added method to code listing so the calling method is visible
@Bean
public StepExecutionRequestHandler stepExecutionRequestHandler() throws Exception {
    StepExecutionRequestHandler result = new StepExecutionRequestHandler();
    ;

    result.setJobExplorer(jobExplorer);
    BeanFactoryStepLocator stepLocator = stepLocator ();
    result.setStepLocator(stepLocator);
    return result;
}
BeanFactoryStepLocator使用applicationContext初始化

@Bean
public ClasspathXmlApplicationContextsFactoryBean classpathXmlApplicationContextsFactoryBean () throws IOException
{
    String resourcePath = configPropertiesService
            .fetchPropertyValue(PropertyValueConstants.MXARCHIVE_SKELETON_LOCATION,
                    PropertyValueConstants.MXARCHIVE_SKELETON_LOCATION_DEFAULT)
            .getValue() + "*.xml";

    logger.trace("classpathXmlApplicationContextsFactoryBean()  :: {} ", resourcePath);
    Resource[] resources = applicationContext.getResources(resourcePath);

    ClasspathXmlApplicationContextsFactoryBean bean = new ClasspathXmlApplicationContextsFactoryBean ();
    bean.setApplicationContext(applicationContext);
    bean.setResources(resources);

    return bean;
}
@Bean
public BeanFactoryStepLocator stepLocator() throws Exception
{
    BeanFactoryStepLocator stepLocator = new BeanFactoryStepLocator ();

/* applicationContext is autowired in the postconstruct - what we do here doesn't matter
    stepLocator.setBeanFactory(applicationContext); // TODO: Find the right factory
    */
    return stepLocator;
};

// EDIT: added method to code listing so the calling method is visible
@Bean
public StepExecutionRequestHandler stepExecutionRequestHandler() throws Exception {
    StepExecutionRequestHandler result = new StepExecutionRequestHandler();
    ;

    result.setJobExplorer(jobExplorer);
    BeanFactoryStepLocator stepLocator = stepLocator ();
    result.setStepLocator(stepLocator);
    return result;
}
在执行时,框架尝试调用该步骤,但失败,因为该步骤不在应用程序上下文(beanFactory)中

步骤XML(已清理)是:

创建时stepLocator中beanFactory的调试器视图

stepLocator()工厂方法结尾处getStep()结果的调试器视图:

编辑2:

看起来原始的“applicationContext”是作为beanfactory自动连接的,所以真正的问题是将额外的bean加载到applicationContext中

@Bean
public ClasspathXmlApplicationContextsFactoryBean classpathXmlApplicationContextsFactoryBean () throws IOException
{
    String resourcePath = configPropertiesService
            .fetchPropertyValue(PropertyValueConstants.MXARCHIVE_SKELETON_LOCATION,
                    PropertyValueConstants.MXARCHIVE_SKELETON_LOCATION_DEFAULT)
            .getValue() + "*.xml";

    logger.trace("classpathXmlApplicationContextsFactoryBean()  :: {} ", resourcePath);
    Resource[] resources = applicationContext.getResources(resourcePath);

    ClasspathXmlApplicationContextsFactoryBean bean = new ClasspathXmlApplicationContextsFactoryBean ();
    bean.setApplicationContext(applicationContext);
    bean.setResources(resources);

    return bean;
}
@Bean
public BeanFactoryStepLocator stepLocator() throws Exception
{
    BeanFactoryStepLocator stepLocator = new BeanFactoryStepLocator ();

/* applicationContext is autowired in the postconstruct - what we do here doesn't matter
    stepLocator.setBeanFactory(applicationContext); // TODO: Find the right factory
    */
    return stepLocator;
};

// EDIT: added method to code listing so the calling method is visible
@Bean
public StepExecutionRequestHandler stepExecutionRequestHandler() throws Exception {
    StepExecutionRequestHandler result = new StepExecutionRequestHandler();
    ;

    result.setJobExplorer(jobExplorer);
    BeanFactoryStepLocator stepLocator = stepLocator ();
    result.setStepLocator(stepLocator);
    return result;
}

我还尝试了在和链接问题上建议的解决方案。

您可以尝试向BeanFactory声明所需的依赖关系,并让Spring提供正确的实例,而不是手动执行查找/注入。因此,不是:

@Bean
public BeanFactoryStepLocator stepLocator() throws Exception {
   BeanFactoryStepLocator stepLocator = new BeanFactoryStepLocator();
   ApplicationContextFactory[] factories = stepFactoryBean().getObject();
   if (factories != null) {         
      stepLocator.setBeanFactory(factories[0].createApplicationContext().getBeanFactory());
   }
   return stepLocator;
};
使用类似于:

@Bean
public StepLocator stepLocator(BeanFactory beanFactory) {
    BeanFactoryStepLocator beanFactoryStepLocator = new BeanFactoryStepLocator();
    beanFactoryStepLocator.setBeanFactory(beanFactory);
    return beanFactoryStepLocator;
}

希望这有帮助。

您可以尝试向BeanFactory声明所需的依赖项,并让Spring提供正确的实例,而不是手动执行查找/注入。因此,不是:

@Bean
public BeanFactoryStepLocator stepLocator() throws Exception {
   BeanFactoryStepLocator stepLocator = new BeanFactoryStepLocator();
   ApplicationContextFactory[] factories = stepFactoryBean().getObject();
   if (factories != null) {         
      stepLocator.setBeanFactory(factories[0].createApplicationContext().getBeanFactory());
   }
   return stepLocator;
};
使用类似于:

@Bean
public StepLocator stepLocator(BeanFactory beanFactory) {
    BeanFactoryStepLocator beanFactoryStepLocator = new BeanFactoryStepLocator();
    beanFactoryStepLocator.setBeanFactory(beanFactory);
    return beanFactoryStepLocator;
}

希望这有帮助。

我已经发现beanFactory属性与根应用程序上下文自动关联,覆盖了我们在代码中设置的任何内容。目前,
stepLocator()
方法仅返回与
applicationContext
自动连接的
newbeanfactorysteplocator()
的结果。如前所述,我可以在applicationContext的
alreadyCreated
属性中看到StepBean,但stepLocator无法找到该步骤。我已更新了代码剪报,以表明设置beanFactory是一件麻烦事。我们是否可以安排一次会议,以便我们可以一起讨论?问题并不是我们期望的那样,我的时间表很紧。谢谢。我建议您在项目()的gitter频道上提问,团队很乐意提供帮助。我已经发现beanFactory属性与根应用程序上下文自动关联,覆盖了我们在代码中设置的任何内容。目前,
stepLocator()
方法仅返回与
applicationContext
自动连接的
newbeanfactorysteplocator()
的结果。如前所述,我可以在applicationContext的
alreadyCreated
属性中看到StepBean,但stepLocator无法找到该步骤。我已更新了代码剪报,以表明设置beanFactory是一件麻烦事。我们是否可以安排一次会议,以便我们可以一起讨论?问题并不是我们期望的那样,我的时间表很紧。谢谢。我建议您在项目的gitter频道()上提问,团队将乐于提供帮助。