0

In my Spring app I noticed strange behavior of Spring (or Eclipse). It confused me. ApplicationContext surrounded with try/catch to be sure is closed after done in finally block. But in Eclipse console I saw that it closed before bean invoked.

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>

In Eclipse console output:

[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] ------------------------------------------------------------------------

As you can see doClose method init before Bean, why? I think that it's Eclipse or maven plugin error... Project was build with exec-maven-plugin.

njjnex
  • 1,490
  • 13
  • 23

1 Answers1

2

Your code is actually working:

The line System.out.println(launcher); prints my.ioc.Launcher@2b7f535d

Just on

INFO: Loading XML bean definitions from class path resource [beans-annot.xml]
my.ioc.Launcher@2b7f535d <--------
окт 30, 2014 8:52:56 PM …..

The line System.out.println("invoke bean"); prints invoke bean just how is expected.. where?

окт 30, 2014 8:52:56 PM ....ClassPathXmlApplicationContext doClose
INFO: Closing org.springframework.context.support….root of context hierarchy
invoke bean <-------- 
[INFO] …

Your application is so short or fast in be executed, that when it is executed, you are seeing the information or output of your own application together with the Spring starting/closing information. So both are printed together, your app and spring (starting/closing) process, so in this case, therefore, the terminal/console is giving the impression you have described.

Try to enclose System.out.println("invoke bean"); within a Thread.sleep(5000) to delay in some way your application.

About your XML application

  1. For each .xsd remove the version, i.e.: spring-beans-3.0.xsd to spring-beans.xsd. It is a good practice not include the version
  2. Remove <context:annotation-config /> is not necessary because you already have <context:component-scan base-package="my.ioc" /> declared, read the following: Difference between <context:annotation-config> vs <context:component-scan> for more details.
Community
  • 1
  • 1
Manuel Jordan
  • 15,253
  • 21
  • 95
  • 158