I am interested in creating a Spring standalone application that will run and wait to receive messages from an ActiveMQ queue using Spring JMS. I have searched a lot of places and cannot find a consistent way of im开发者_StackOverflow社区plementing the main method for such a standalone application. There appears to be few examples of Spring standalone applications. I have looked at Tomcat, JBoss, ActiveMQ and other examples from the around the web but I have not come to a conclusion so ...
What is the best practice for implementing a main method for a Java application (specifically Spring with JMS) ?
Update: Here's an example from: http://forum.springsource.org/showthread.php?t=48197 Is this the best way of doing this?
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();
}
}
When using Spring JMS you already use components/beans in your configuration that get auto-started and will stay alive (subscribe and read from queue/topic) until you stop the application.
To start and keep the application running, loading the applicationcontext should therefore be enough. Good practice though is to also call the registerShutdownHook, so on a application halt (i.e via ctrl+c in the console), al your beans are gracefully shutdown and disposed :)
public static void main(String args[]) {
AbstractApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
context.registerShutdownHook();
}
This is what we have, inside app-context.xml we use spring JMS classes like (org.springframework.jms.listener.DefaultMessageListenerContainer to manage number of consumers and provide custom listener using org.springframework.jms.listener.adapter.MessageListenerAdapter)
app-context.xml contains all spring beans listeners and other stuff, the code below is bootstrapping Spring provided listeners on queues. So idea is to use Spring classes to manage multiple consumers. Let me know if this is what you need and need more information on configuring MessageListenerAdapter.
public static void main(String[] args)
{
try
{
new ClassPathXmlApplicationContext("app-context.xml");
}
catch (Throwable e)
{
e.printStackTrace();
System.exit(-1);
}
}
The main idea is to make main thread wait until app will be finished. while(!finished) is correct way to wait until main thread will be wake up.
finishEventHandler - is a method that handles finish/quit event.
I consider that JMS initialization is done in Spring conf. and in ". . . . ." section.
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();
}
In your main() do something like this:
// 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()
You would inject your Utiltity bean with Spring's JMS template to do the gruntwork for your usecase.
Attempt a read in a loop. If a message is found, process it, then sleep and iterate again. Also put some sort of terminator logic in there (interrupt the thread). You could terminate after X attempts, read from a file, kill the JVM, read a terminator msg from the queue, etc., etc.
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;
}
}
}
精彩评论