spring - 结合 Spring、Quartz 调度和 Hazelcast

标签 spring quartz-scheduler hazelcast

我正在尝试弄清楚如何为我正在编写的网络应用程序开发一个合理可扩展的批处理框架。

我正在将 Spring MVC 用于 Web 应用程序,并具有自定义 DAO 层(要访问数据库,需要从设置的 UnitOfWorkFactory 构造 UnitOfWork 实例作为 @Autowired 并在运行时由 Spring 注入(inject))。

我正在使用 Spring Scheduler 注释 (@Scheduled) 来安排任务,但是我希望这些任务在集群中的不同计算机上运行。每个批处理作业应由其中一台集群机器拾取并执行。

Hazelcast似乎很适合这个,因为 Distributed Execution为此目的,设计显得非常简单和优雅。

我遇到了一个似乎没有被文档涵盖的问题。我已阅读有关 Spring Integration 的文档然而,这似乎集中在如何使用 Spring 配置 Hazelcast(我已经完成了)。

当调度程序指示任务要启动时,我想创建一个新的任务实例(Callable 实例)并将其提交给DistributedExecutor。当集群机器收到要运行的任务时,我需要集群机器上的 Spring 容器在任务尝试执行批处理任务之前将 UnitOfWorkFactory 实例注入(inject)到批处理任务中。每个集群都从 Spring 开始,并且已经使用正确的详细信息实例化了 UnitOfWorkFactory,问题在于将 UnitOfWorkFactory 实例注入(inject)到我的任务中。

有谁知道如何配置我的应用程序,以便 Hazelcast 可以在 Callable 启动时自动注入(inject) UnitOfWorkFactory ?我已尝试将Callable标记为可序列化和ApplicationContextAware,但在尝试运行任务时仍然遇到NullPointerException

我可以直接访问 ApplicationContext,但我不愿意,因为它会限制我的任务的可测试性,并为我的批处理作业引入对 Spring 的硬依赖。

最佳答案

到版本 2.1 Hazelcast 可以将 Spring 上下文和/或 Spring beans 注入(inject)到 Hazelcast 托管对象中。

如果您使用 Hazelcast Spring 配置来配置 Hazelcast,并使用 @SpringAware 注释一个 bean,Hazelcast 将要求 Spring 注入(inject)该 bean 的依赖项。

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:hz="http://www.hazelcast.com/schema/spring"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.hazelcast.com/schema/spring
            http://www.hazelcast.com/schema/spring/hazelcast-spring-2.1.xsd">
   <hz:hazelcast id="instance">
      <hz:config>
         <hz:group name="dev" password="password"/>
         <hz:network port="5701" port-auto-increment="false">
            <hz:join>
                <hz:multicast enabled="false" />
                <hz:tcp-ip enabled="true">
                    <hz:members>10.10.1.2, 10.10.1.3</hz:members>
                </hz:tcp-ip>
            </hz:join>
         </hz:network>
         ...
      </hz:config>
   </hz:hazelcast>

   <bean id="someBean" class="com.hazelcast.examples.spring.SomeBean" 
          scope="singleton" />
   ...
</beans>
<小时/>
@SpringAware 
public class SomeTask implements Callable<Long>, ApplicationContextAware, Serializable {
   private transient ApplicationContext context;
   private transient SomeBean someBean;

   public Long call() throws Exception {
     return someBean.value;
   }

   public void setApplicationContext(final ApplicationContext applicationContext)
       throws BeansException {
      context = applicationContext;
   }

   @Autowired
   public void setSomeBean(final SomeBean someBean) {
      this.someBean = someBean;
   }
}
<小时/>

For older versions than 2.1:

Hazelcast 2.1 之前的版本不支持 Spring,因此无法将 Spring 上下文或任何 Spring bean 注入(inject)到 2.1 之前版本的 Hazelcast 托管对象中。

Hazelcast 群组上有一篇帖子询问此功能。

Hazelcast / Dependency injection for Callable

正如您可能已经知道并在 Hazelcast 组中建议的那样,您可以使用以下方式访问 Spring ApplicationContext:

public class ApplicationContextProvider implements ApplicationContextAware {
    private static ApplicationContext context = null;

    public synchronized void setApplicationContext(ApplicationContext applicationContext)
        throws BeansException {
        if(context == null) {
            context = applicationContext;
        }
    }

    public static <T> T getBean(String name) {
        return (T) context.getBean(name);
    }
}  

class MyCallable implements Callable {
    ....
    public Object call() throws Exception {
        SomeServiceBean bean = ApplicationContextProvider.getBean("serviceBean");
        ....
    }
}

关于spring - 结合 Spring、Quartz 调度和 Hazelcast,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8652318/

相关文章:

java - 如何从父项目的不同jar访问服务

java - quartz 触发器已成为过去

java - 使用 -cluster 选项启动时 Vert.x 性能下降

java - 为 hazelcast 创建自定义发现策略时出现问题

java - Hazelcast:在集群上部署的正确方法

spring - 我需要为哪些实体创建 Spring Data 存储库?

java - 如何在 Spring MVC 中捕获所有未处理的异常(即没有现有的@ExceptionHandler)?

Java EE 6 注入(inject)创建不同的策略

java - 无法存储作业 : Driver's Blob representation is of an unsupported type: oracle. sql.BLOB [请参阅嵌套异常 : java. sql.SQLException

java - 如何禁用 Quartz 更新尝试?