对于独立应用程序(对于 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 方法应该是啥?的主要内容,如果未能解决你的问题,请参考以下文章
Spring整合JMS——三种connectionFactory
@SendTo Annotation 对于 ActiveMQ 静默失败