public static void main(String[] args) {
LOGGER.info("==启动APP日志队列程序=="); SpringUtils.getBean(UserAppLogConsumerListener.class); }
一开始我是使用自定义的spring工具类的getBean方法进行初始化,但是存在问题:配置文件中用有引用UserAppLogConsumerListener这个bean,导致报错expected single matching bean but found 2
Exception in thread "main" org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.cdd.rabbitmq.consume.listener.UserAppLogConsumerListener' available: expected single matching bean but found 2: userAppLogConsumerListener,userAppReceiver at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1039) at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:339) at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:334) at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1107) at com.cdd.core.utils.SpringUtils.getBean(SpringUtils.java:28) at com.cdd.rabbitmq.consume.Main.main(Main.java:23)
然后换了一种方式,直接根据配置文件加载ApplicationContext,成功
public static void main(String[] args) { LOGGER.info("==启动APP日志队列程序=="); // SpringUtils.getBean(UserAppLogConsumerListener.class); ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); }
继续找了一下资料,发现Spring在非web应用中关闭IoC容器需要在JVM里注册一个“关闭钩子”(shutdown hook),这样会确保你的Spring IoC容器被恰当关闭,以及所有由单例持有的资源都会被释放。
为了注册“关闭钩子”,你只需要简单地调用在org.springframework.context.support.AbstractApplicationContext实现中的registerShutdownHook()方法即可。
对于关闭钩子和start()方法的作用还不太理解,在网上找的介绍如下:
关闭钩子网上介绍的作用:Java Runtime注册的ShutdownHook在JVM进程正常关闭(操作系统正常关闭,用户调用System.exit(0), kill, Ctrl+C等)执行,Spring注册这个旨在正常关闭的时候关闭(代码中的doClose())容器。关闭容器的时候,会释放所有容器管理Bean,同时如果容器管理Bean声明了销毁回调方法也会执行(典型的就是数据库连接池的关闭,执行线程池的关闭等)以释放资源。不过kill -9,拔电等不在此讨论范围。
start()方法的作用在于,启动某个组件,如果该组件已经启动则不抛出异常,如果启动的是某个container,则会将启动信号扩散至该容器内部的所有组件。
最终代码:
public static void main(String[] args) { LOGGER.info("==启动APP日志队列程序=="); ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); context.registerShutdownHook(); context.start(); }