在我的 Spring 应用程序中,我注意到 Spring(或 Eclipse)的奇怪行为。这让我很困惑。 ApplicationContext 被 try/catch 包围,以确保在 finally block 中完成后关闭。但在 Eclipse 控制台中,我看到它在调用 bean 之前关闭。
public class Main {
public static void main(String[] args) {
ApplicationContext context = null;
try {
context = new ClassPathXmlApplicationContext(new String[] { "beans-annot.xml" });
Launcher launcher = (Launcher) context.getBean("launcher");
System.out.println(launcher);
launcher.invokeBean();
} catch (BeansException e) {
e.printStackTrace();
} finally {
if(context != null)
((AbstractApplicationContext) context).close();
}
}
}
@Component
public class Bean {
public void invoke(){
System.out.println("invoke bean");
}
}
@Component
public class Launcher {
@Autowired
public Bean bean;
//setter
public void invokeBean(){
bean.invoke();
}
}
beans-annot.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="my.ioc" />
<context:annotation-config />
</beans>
在 Eclipse 控制台输出中:
[INFO] --- exec-maven-plugin:1.2.1:java (default-cli) @ IoC ---
окт 30, 2014 8:52:56 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@6e4e4adb: startup date [Thu Oct 30 20:52:56 FET 2014]; root of context hierarchy
окт 30, 2014 8:52:56 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [beans-annot.xml]
my.ioc.Launcher@2b7f535d
окт 30, 2014 8:52:56 PM org.springframework.context.support.ClassPathXmlApplicationContext doClose
INFO: Closing org.springframework.context.support.ClassPathXmlApplicationContext@6e4e4adb: startup date [Thu Oct 30 20:52:56 FET 2014]; root of context hierarchy
invoke bean
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
正如你所看到的,doClose方法在Bean之前初始化,为什么呢?我认为这是 Eclipse 或 maven 插件错误...项目是使用 exec-maven-plugin 构建的。
最佳答案
您的代码实际上正在运行:
线路System.out.println(launcher);
打印my.ioc.Launcher@2b7f535d
就在
INFO: Loading XML bean definitions from class path resource [beans-annot.xml]
my.ioc.Launcher@2b7f535d <--------
окт 30, 2014 8:52:56 PM …..
线路System.out.println("invoke bean");
打印invoke bean
到底是怎样的预期......在哪里?
окт 30, 2014 8:52:56 PM ....ClassPathXmlApplicationContext doClose
INFO: Closing org.springframework.context.support….root of context hierarchy
invoke bean <--------
[INFO] …
您的应用程序的执行时间非常短或非常快,以至于当它执行时,您将看到您自己的应用程序的信息或输出一起以及 Spring 启动/关闭信息。因此,您的应用程序和 Spring (启动/关闭)过程都一起打印,因此在这种情况下,终端/控制台给出了您所描述的印象。
尝试将 System.out.println("invoke bean");
括起来在Thread.sleep(5000)
内以某种方式延迟您的申请。
关于您的 XML 应用程序
- 对于每个 .xsd,删除版本,即:spring-beans-3.0.xsd 到 spring-beans.xsd。 不包含版本是一个很好的做法
- 删除
<context:annotation-config />
不是必需的,因为您已经有<context:component-scan base-package="my.ioc" />
声明,请阅读以下内容:Difference between <context:annotation-config> vs <context:component-scan>
了解更多详情。
关于java - Spring ApplicationContext 在 bean 调用之前关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26659457/