使用Play初始化消费者模块!框架

时间:2016-07-12 20:06:18

标签: java jpa playframework rabbitmq guice

我有一个我想要启动的ConsumerService的Play应用程序,让它在启动时侦听特定的RabbitMQ队列。在玩! 2.5,我的理解是现在通过指南模块完成,所以我在我的应用程序根目录中直接有一个Module.java类,如下所示:

public class Module extends AbstractModule {

  @Override
  protected void configure() {
    bind(ConsumerService.class).asEagerSingleton();
  }
}

这是我的ConsumerService类:

@Singleton
public class ConsumerService {

  private static final String TASK_QUEUE_NAME = "queue";
  private final JPAApi jpaApi;

  @Inject
  public ConsumerService(JPAApi api) throws Exception {
    this.jpaApi = api;
    pullMessages();

  }

  @Transactional
  public void pullMessages() throws Exception {

    ConnectionFactory factory = new ConnectionFactory();
    factory.setHost("localhost");
    final Connection connection = factory.newConnection();
    final Channel channel = connection.createChannel();

    channel.queueDeclare(TASK_QUEUE_NAME, true, false, false, null);
    Logger.info(" [*] Waiting for messagez. To exit press CTRL+C");

    channel.basicQos(1);

    final Consumer consumer = new DefaultConsumer(channel) {

      @Override
      public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
        try {
          JPA.em();
        } catch (Exception e) {
          System.out.println("JPA.em() failed: " + e.getMessage());
        }
        try {
          jpaApi.em();
        } catch (Exception e) {
          System.out.println("jpaApi.em() failed: " + e.getMessage());
        }

      }
    };
    channel.basicConsume(TASK_QUEUE_NAME, false, consumer);
  }
}

将此服务明确地绑定为Eager Singleton有其缺点,因为尝试通过这些方法之一获取entityManager会引发异常。我的理解是,这是因为在Play初始化EntityManager工厂之前,这个类是绑定/加载的。基本上应用程序还没有开始。

请原谅我,但即使我已经使用JPA多年,我发现这非常令人困惑,并且不确定我应该解决基本问题的最佳方法:启动一个“监听器”,最终需要做一些消耗消息时的数据库操作。

我很好奇是否可以在事务中放置“handleDelivery”方法,或重新设计初始化流程,以便我可以干净地调用/注入jpaApi。

另外,有没有办法在Play 2.5中启动这个消费者,而不是我在这里做的方式?我找不到这个。

我查看了JPAApi.withTransaction文档,但我希望有一种更好的方法,我不知道。

0 个答案:

没有答案