0

我使用 MySQL 5.5、Glassfish 3.1.2 和一个独立的 Swing 客户端 (JRE 6_u32) 构建了一个 3 层应用程序。我计划在 Glassfish 服务器上运行一个 GUI 更新服务,以便当前连接到应用程序服务器的任何用户在另一个用户创建、修改或删除 @Entity 注释对象时得到通知。

为此,我计划在实体侦听器调用任何回调方法(@PostPersist、@PostUpdate、@PostRemove)时充当 JMS 主题生产者的会话 bean。因此,独立的 Swing 客户端充当主题的 JMS 消息消费者。

我的应用程序包含 3 个项目。首先,EJB 项目女巫在服务器容器中运行并持有外观会话 bean,这是一个类库项目,它持有 @Entity 注释类和远程外观接口(这个由 EJB 项目和独立的 Swing 客户端共享- 通信目的),最后是管理 GUI 的独立 Swing 客户端。@Singleton 类是 classlib 项目的一部分,因此我不能在那里使用依赖注入。此外,我认为这正是问题所在,@Singleton 类不是容器管理的,因为它被打包在自己的 jar-lib 中并被 EJB 项目引用(必须使用 JNDI 查找)。

你会推荐什么样的 Session Bean 来在应用服务器上实现主题消息生产者?单例、有状态、无状态、消息驱动?

这是我现在的singelton session bean。问题是,@PostConstruct 注释的 initConnection 方法没有被调用。调用 publishCreated() 时,“会话”和“发布者”字段为空...

任何想法如何解决这个问题?提前谢谢了!

@Singleton
public class UpdateService {

    private Destination topic;
    private ConnectionFactory factory;
    private Connection connection;
    private Session session;
    private MessageProducer producer;

    public UpdateService() { }

    @PostConstruct void initConnection() {
        try {
            InitialContext ctx = ServerContext.getInitialContext();
            factory = (TopicConnectionFactory)ctx.lookup("jms/TopicFactory");
            topic = (Topic)ctx.lookup("jms/TopicUpdate");
            connection = factory.createConnection();
            session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
            producer = session.createProducer(topic);
        } catch (NamingException ex) {
            Logger.getLogger(UpdateService.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
        } catch (JMSException ex) {
            Logger.getLogger(UpdateService.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
        }
    }

    @PreDestroy void closeConnection() {
        try {
            session.close();
            connection.close();
        } catch (JMSException ex) {
            Logger.getLogger(UpdateService.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
        }
    }

    @PostPersist void publishCreated(IUpdateableEntity entity) throws JMSException {
        if(session!=null && producer!=null) {
            ObjectMessage message = session.createObjectMessage(new UpdateMessage(entity, UpdateType.CREATED));
            producer.send(message);
        }
    }

    @PostUpdate void publishUpdated(IUpdateableEntity entity) throws JMSException {
        if(session!=null && producer!=null) {
            ObjectMessage message = session.createObjectMessage(new UpdateMessage(entity, UpdateType.MODIFIED));
            producer.send(message);
        }
    }

    @PostRemove void publishRemoved(IUpdateableEntity entity) throws JMSException {
        if(session!=null && producer!=null) {
            ObjectMessage message = session.createObjectMessage(new UpdateMessage(entity, UpdateType.REMOVED));
            producer.send(message);
        }
    }

}
4

1 回答 1

1

它的服务器负责在初始化 bean 时注入依赖项。您可以尝试使用注解来注入这些 JMS 资源。

@Startup
@Singleton
public class UpdateService {

    @Resource(mappedName = "jms/TopicFactory")
    private ConnectionFactory connectionFactory;

    @Resource(mappedName = "jms/TopicUpdate")
    private Topic replyToTestQueue;

    @PostConstruct
    void initConnection() {

          //-- Messaging Configuration 
    }
}

确保通过管理控制台正确配置了这些资源。我不习惯 Glassfish,但我已经尝试过并且它工作正常。

但是,默认情况下,所有单例方法都是事务性和线程安全的,您可以通过显式锁定来管理并发。否则,如果它适合,您可以使用无状态 bean。

于 2012-05-31T18:40:12.373 回答