java - Spring ApplicationContext 在 bean 调用之前关闭

标签 java eclipse spring maven

在我的 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 应用程序

  1. 对于每个 .xsd,删除版本,即:spring-beans-3.0.xsd 到 spring-beans.xsd。 包含版本是一个很好的做法
  2. 删除 <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/

相关文章:

java - HashMap、LinkedHashMap 和 ConcurrentHashMap 在创建 Map 和基于特定键获取值时的执行成本

java - 如何测试 'Limited Access' 到 Internet

java - 如何在不使用 DB 工具的情况下检测 Java 应用程序中的连接泄漏/打开连接

mysql - Spring Data 的 SQL 语句 - PersistentEntity 不能为 null

java - "Maven Surefire plugin"在测试您的构建时意味着什么?

eclipse - 如何设置 ZendStudio 不删除尾随空格?

java - 如何在 Java 中从 Selenium Webdriver 调用书签?

java - Spring Boot Rest API 安全性

java - 如何使用 Spring Boot、JPA 和 Thymeleaf 设置搜索栏

Eclipse 插件依赖消失