在 Spring Batch 中访问步骤范围之外的 Bean

2024-01-10

是否可以访问步骤范围之外定义的 bean?例如,如果我定义策略“strategyA”并将其传递到作业参数中,我希望@Value 解析为strategyA bean。这可能吗?我目前正在通过从 applicationContext 手动获取 bean 来解决该问题。

@Bean
@StepScope
public Tasklet myTasklet(
        @Value("#{jobParameters['strategy']}") MyCustomClass myCustomStrategy)

    MyTasklet myTasklet= new yTasklet();

    myTasklet.setStrategy(myCustomStrategy);

    return myTasklet;
}

我希望能够添加更多策略而无需修改代码。


答案是肯定的。这是比 Spring Batch 更通用的 spring/设计模式问题评估器。
Spring Batch 的棘手部分是配置和理解 bean 创建的范围。
假设您的所有策略都实现策略接口,如下所示:

interface Strategy {
    int execute(int a, int b); 
};

每个策略都应该实现 Strategy 并使用 @Component 注解来允许自动的发现新策略。确保所有新策略都放置在正确的包下,以便组件扫描能够找到它们。
例如:

@Component
public class StrategyA implements Strategy {
    @Override
    public int execute(int a, int b) {
        return a+b;
    }
}

以上是单例,将在应用程序上下文初始化时创建。
此阶段使用 @Value("#{jobParameters['strategy']}") 还为时过早,因为尚未创建 JobParameter。

因此,我建议使用稍后创建 myTasklet 时使用的定位器 bean(步骤范围)。

策略定位器类:

public class StrategyLocator {
    private Map<String, ? extends Strategy> strategyMap;

    public Strategy lookup(String strategy) {
        return strategyMap.get(strategy);
    }

    public void setStrategyMap(Map<String, ? extends Strategy> strategyMap) {
        this.strategyMap = strategyMap;
    }

}

配置将如下所示:

@Bean
@StepScope
public MyTaskelt myTasklet () {
      MyTaskelt myTasklet = new MyTaskelt();
      //set the strategyLocator
      myTasklet.setStrategyLocator(strategyLocator());
      return myTasklet;
}
@Bean 
protected StrategyLocator strategyLocator(){
    return  = new StrategyLocator();    
}    

要初始化 StrategyLocator,我们需要确保所有策略都已创建。因此,最好的方法是在 ContextRefreshedEvent 事件上使用 ApplicationListener(警告在此示例中策略名称以小写字母开头,更改它很容易......)。

@Component
public class PlugableStrategyMapper implements ApplicationListener<ContextRefreshedEvent> {
    @Autowired
    private StrategyLocator strategyLocator;
    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        ApplicationContext applicationContext = contextRefreshedEvent.getApplicationContext();
        Map<String, Strategy> beansOfTypeStrategy = applicationContext.getBeansOfType(Strategy.class);
        strategyLocator.setStrategyMap(beansOfTypeStrategy);        
    }

}

tasklet 将保存一个 String 类型的字段,该字段将使用 @Value 注入策略枚举字符串,并将使用“before step”侦听器使用定位器进行解析。

    public class MyTaskelt implements Tasklet,StepExecutionListener {
        @Value("#{jobParameters['strategy']}")
        private String strategyName;
        private Strategy strategy;
        private StrategyLocator strategyLocator;

        @BeforeStep
        public void beforeStep(StepExecution stepExecution) {
            strategy = strategyLocator.lookup(strategyName);        
        }
        @Override
        public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
            int executeStrategyResult = strategy.execute(1, 2); 
        }
           public void setStrategyLocator(StrategyLocator strategyLocator) {
               this.strategyLocator = strategyLocator;
           }
    }

要将侦听器附加到 taskelt,您需要在步骤配置中设置它:

@Bean
protected Step myTaskletstep() throws MalformedURLException {
     return steps.get("myTaskletstep")
    .transactionManager(transactionManager())
    .tasklet(deleteFileTaskelt())
    .listener(deleteFileTaskelt())
    .build();
 }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Spring Batch 中访问步骤范围之外的 Bean 的相关文章

随机推荐

  • 视图左上角的 GMSMarker 图标 (iOS)

    我正在尝试创建一个包含 GMSMapView 的 UITableViewCell 其中 GMSMarker 位于当前位置的中心 问题是标记总是出现在当前位置的左上角 我不知道如何解决这个问题 我尝试按照以下步骤操作 使用 UItablevi
  • 什么是 { 得到;放; C# 中的语法?

    我正在学习 ASP NET MVC 我可以阅读英文文档 但我不太明白这段代码中发生了什么 public class Genre public string Name get set 这是什么意思 get set 它是所谓的 auto 属性
  • 更改 NSDictionary 中的键名

    我有一个方法 它返回一个带有某些键和值的 nsdictionary 我需要将字典中的键名称更改为新的键名称 但该键的值需要相同 但我被困在这里 需要帮助 此方法仅适用于可变字典 如果新密钥已经存在 它不会检查应该做什么 您可以通过调用 mu
  • 在 Visual C# 中从 RichTextBox 中删除 RichText 格式

    我正在用 C 开发一个高级富文本编辑器 但偶然发现了一个我似乎无法理解的问题 我一直试图让用户将他们的文档保存为文本文件 纯文本 通过使用以下内容 我的 RichTextBox Save 文件 文件路径 PlainText 但问题是 当他们
  • 1.8 与 1.9 中的 BigDecimal

    升级到 ruby 1 9 时 在比较预期值与实际值时 我的测试失败了BigDecimal这是 Float 除法的结果 expected 0 495E0 9 18 got 0 4950000000 0000005E0 18 27 谷歌搜索 b
  • CSS 第一次在 3D 变换时不渲染背面

    我有一个卡片翻转风格的动画 可以将文本区域翻转 180 度 我遇到的唯一问题是 第一次执行翻转时 在经过 90 度后 元素消失 然后在完成 180 度旋转后出现后面的元素 这是带有代码的示例 http jsfiddle net elninj
  • 阻止用户删除 BigQuery 表

    我们正在尝试创建一个非常基本的角色 允许用户查询 BigQuery 表 但不能删除它们 我们正在试验的自定义角色现在具有以下权限 bigquery jobs create bigquery jobs get bigquery jobs li
  • 如何清除 Selectize.js 下拉列表中的选定值?

    我有一个selectize js https selectize github io selectize js 下拉菜单 我必须清除所选值 我已经尝试过这个 如建议的另一个问题 https stackoverflow com questio
  • Nexus 10 Camera.release 挂起 30 秒

    我们是一群正在开发 Android 实时视频处理应用程序的开发人员 最近 一位客户报告我们的应用程序出现冻结 这种情况仅发生在 Nexus 10 设备上 我们自己购买了设备并进行了测试 设备预装了 Android 4 2 我们的应用程序没有
  • 如何将带有 alpha 的 PNG 转换为 RGBA4444 以便在 SpriteKit SKTexture 中使用?

    我有一堆透明 PNG 我想在SKSpriteNode动画与SKTextures 我需要调整内存使用情况SKTextures 通过降低纹理质量RGBA8888 to RGBA4444 我将如何初始化SKTexture with RGBA444
  • 带有子类的构造函数中的 Object.freeze

    如果我希望我的类不可变 我知道我可以使用Object freeze 现在 如果我希望我的对象在构造后不可变 我会放Object freeze this 作为最后一行进入我的构造函数 但现在 如果我想子类化它 我无法添加更多参数 因为我无法调
  • 在 React.js 中检索复选框的值

    我想在选中复选框时检索它的值 我正在使用这个 http react component github io checkbox http react component github io checkbox 我的代码看起来像这样 div ch
  • 如何设置密码最小长度

    我目前正在制作 html 表单 如何将密码的最小长度设置为8 以便拒绝用户输入小于8的密码 如何做到这一点 这是代码 div div
  • 使用 mvcmailer 发送多封电子邮件

    我想使用MVC邮件程序 https github com smsohan MvcMailer wiki MvcMailer Step by Step Guide使用 asp net mvc 3 和 razor 发送电子邮件 还提到过Scot
  • 如何在 postgresql 中将 DELETE 的返回插入到 INSERT 中?

    我正在尝试从一个表中删除一行并将其与一些附加数据插入到另一个表中 我知道这可以通过两个单独的命令来完成 一个用于删除 另一个用于插入新表 然而我试图将它们结合起来但它不起作用 这是我到目前为止的查询 insert into b one tw
  • Django - 基于函数的视图 (FBV) 不允许使用方法

    我得到了405 METHOD NOT ALLOWED当我尝试通过 AJAX 调用提交 POST 请求时的响应 POST events profile update HTTP 1 1 405 0 我试图用最基本的视图来设置它 def prof
  • 重写抽象类以返回硬编码方法值

    我想从这里覆盖 CoreUtils 抽象类https docs spring io spring framework docs current javadoc api org springframework web cors reactiv
  • Laravel 路由重定向而不关闭路由缓存

    我的电脑上有这个代码routes php执行重定向的文件 虽然问题是每当我跑步时php artisan route cache命令 它给了我一个错误Unable to prepare route article params for ser
  • 用于网络请求的 AsyncTask 与 ThreadPoolExecutor

    我正在开发一个项目 我需要点击 Web 服务下载 JSON 数据并将其表示在列表中 所有列表项都有缩略图 URL 可以下载并显示在列表项中 我已经使用 ThreadPoolExecutor 和 AsyncTask 完成了整个调用部分 但从设
  • 在 Spring Batch 中访问步骤范围之外的 Bean

    是否可以访问步骤范围之外定义的 bean 例如 如果我定义策略 strategyA 并将其传递到作业参数中 我希望 Value 解析为strategyA bean 这可能吗 我目前正在通过从 applicationContext 手动获取