对于独立应用程序(对于 Spring JMS),Java main 方法应该是啥?

Posted

技术标签:

【中文标题】对于独立应用程序(对于 Spring JMS),Java main 方法应该是啥?【英文标题】:What should the Java main method be for a standalone application (for Spring JMS)?对于独立应用程序(对于 Spring JMS),Java main 方法应该是什么? 【发布时间】:2011-01-30 15:45:06 【问题描述】:

我有兴趣创建一个 Spring 独立应用程序,该应用程序将运行并等待使用 Spring JMS 从 ActiveMQ 队列接收消息。我搜索了很多地方,但找不到一致的方式来实现这样一个独立应用程序的主要方法。 Spring 独立应用程序的示例似乎很少。我从网上查看了 Tomcat、JBoss、ActiveMQ 和其他示例,但我还没有得出结论,所以......

为 Java 应用程序(特别是 Spring with JMS)实现 main 方法的最佳实践是什么?

更新: 下面是一个例子:http://forum.springsource.org/showthread.php?t=48197 这是最好的方法吗?

public static void main(String args[]) 
        try 
           ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
            . . . . .
            Object lock = new Object();
            synchronized (lock) 
                lock.wait();  
            

         catch (Exception e) 
            e.printStackTrace();
        

【问题讨论】:

【参考方案1】:

尝试循环读取。如果找到一条消息,则对其进行处理,然后休眠并再次迭代。还要在其中放置某种终结符逻辑(中断线程)。您可以在 X 次尝试后终止、从文件中读取、终止 JVM、从队列中读取终止符消息等等。

public static void main(String[] args) 
    while(true) 
        // look for some terminator
        // attempt to read off queue
        // process message
        try 
            TimeUnit.SECONDS.sleep(5);
         catch (Exception e) 
            break;
        
    

【讨论】:

我可能错了,但我认为这会导致两个方面的性能问题: 1. 不断处理的 while 循环会消耗处理器。 2. 睡眠会导致处理消息的延迟(因为框架会处理这个问题,所以没有那么大的问题)。我认为答案将涉及锁定主要方法,但我不确定。 不知道What is the best practice for implementing a main method for a Java application 与 Spring 有什么关系。如果他的问题是How do I obtain a bean from a Spring config,那你的回答就太好了。 @Brandon,在另一个线程中处理消息,即在 Runnable 内。【参考方案2】:

在你的 main() 中做这样的事情:

// gather config files
String[] configs =  "classpath:applicationContext-myutil.xml" ;

// create the app context
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(configs);

// obtain reference to your utility bean
MyUtilityBean utility = (MyUtilityBean) ctx.getBean("utility");

// invoke methods on your utility bean
utility.doSomething()

您可以使用Spring's JMS template 注入您的实用程序bean 来为您的用例完成繁琐的工作。

【讨论】:

我想我在想一些类似的东西:forum.springsource.org/showthread.php?t=48197 因为 bean 方法是注意执行任何东西只是等待接收消息。 这与Java应用程序中的主要方法有什么关系。 我提供了更新。我认为问题是隐含的。 我认为您应该配置一个消息驱动 Pojo,如下所述:static.springsource.org/spring/docs/3.0.x/… 这将消除您必须执行的轮询消息的编程。 Spring会为你做这件事,所以你不会出错:)【参考方案3】:

这就是我们所拥有的,在 app-context.xml 中,我们使用 spring JMS 类(如 org.springframework.jms.listener.DefaultMessageListenerContainer 来管理消费者数量并使用 提供自定义监听器) >org.springframework.jms.listener.adapter.MessageListenerAdapter)

app-context.xml 包含所有 spring bean 侦听器和其他内容,下面的代码是引导 Spring 在队列中提供的侦听器。所以想法是使用Spring类来管理多个消费者。让我知道这是否是您需要的,并且需要有关配置 MessageListenerAdapter 的更多信息。

public static void main(String[] args)


    try
    
        new ClassPathXmlApplicationContext("app-context.xml");

    
    catch (Throwable e)
    
        e.printStackTrace();
        System.exit(-1);
    


【讨论】:

【参考方案4】:

主要思想是让主线程等到应用程序完成。 while(!finished) 是等待主线程被唤醒的正确方法。

finishEventHandler - 是一种处理完成/退出事件的方法。

我认为 JMS 初始化是在 Spring conf 中完成的。并在“……”中部分。

public static void main(String args[]) 

try 
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        lock = new Object();

        while(!finished) 
           synchronized (lock) 
               lock.wait();  
           
        

     catch (Exception e) 
        e.printStackTrace();
    

 public void finishEventHandler() 
     finished = true;
     lock.notify();

【讨论】:

【参考方案5】:

使用 Spring JMS 时,您已经在配置中使用了组件/bean,这些组件/bean 会自动启动,并且会保持活动状态(订阅并从队列/主题中读取),直到您停止应用程序。

因此,要启动并保持应用程序运行,加载应用程序上下文就足够了。 好的做法是同时调用 registerShutdownHook,因此在应用程序停止时(即通过控制台中的 ctrl+c),您的所有 bean 都会正常关闭和处理:)

public static void main(String args[]) 
    AbstractApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
    context.registerShutdownHook();

【讨论】:

对于寻找类配置方法(vs XML)的人,您可以使用AnnotationConfigApplicationContext。我这里有一个例子***.com/a/15914136/311525。

以上是关于对于独立应用程序(对于 Spring JMS),Java main 方法应该是啥?的主要内容,如果未能解决你的问题,请参考以下文章

JDBC和JMS的Spring事务同步

Spring整合JMS——三种connectionFactory

@SendTo Annotation 对于 ActiveMQ 静默失败

消息中间件ActiveMQ及Spring整合JMS的介绍

JMS与Spring( 二)(用message listener container异步收发消息)

JMS与Spring( 二)(用message listener container异步收发消息)