Spring: инициализирующий метод компонента запускается при вызове других компонентов

#spring

#spring

Вопрос:

В настоящее время я экспериментирую с методами обратного вызова компонента и заметил, что если я определяю методы обратного вызова для одного компонента, эти методы также вызываются для других компонентов.

У меня есть классы с именами x.HelloWorld (без обратных вызовов) и y.HelloWorld (имеет методы обратного вызова init и destroy).

HelloWorld.java:

 public class HelloWorld {
    private String message;

    public void setMessage(String message) {
        this.message = message;
    }

    public void getMessage() {
        System.out.println("Your Message : "   message);
    }
}
  

HelloWorld2.java:

 public class HelloWorld {
    private String message;

    public void setMessage(String message) {
        this.message = message;
    }

    public void getMessage() {
        System.out.println("Your Message : "   message);
    }

    public void init() {
        System.out.println("Bean is going through init.");
    }

    public void destroy() {
        System.out.println("Bean will destroy now.");
    }
}
  

x.MainApp.java:

 import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
    public static void main(String[] args) {

        AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");

        HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
        obj.getMessage();
    }
}
  

y.MainApp.java:

 import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
    public static void main(String[] args) {

        AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");

        HelloWorld obj = (HelloWorld) context.getBean("helloWorld2");
        obj.getMessage();
        context.registerShutdownHook();
    }
} 
  

beans.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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.3.xsd">

    <bean id="helloWorld" class="x.HelloWorld">
        <property name="message" value="Hello World (1)" />
    </bean>
    <bean id="helloWorld2" class="y.HelloWorld"
        init-method="init" destroy-method="destroy">
        <property name="message" value="Hello World (2)" />
    </bean> 
</beans>
  

Результаты:
Выполняется y.MainApp (работает, как ожидалось):

 Bean is going through init. 
Your Message : Hello World (2)
Bean will destroy now.
  

Выполняется x.MainApp (обратный вызов init x.HelloWorld запускается y.HelloWorld . Запутался в этом .. любая помощь очень ценится …)

 Bean is going through init.
Your Message : Hello World (1)
  

Комментарии:

1. Если вы поместите другой метод инициализации в x.MainApp, он тоже будет запущен. Вы создаете новый контекст приложения с указанной конфигурацией xml, но это не означает, что все компоненты загружаются в момент создания контекста.

Ответ №1:

Пожалуйста, измените свой метод инициализации следующим образом:

 public void init() {
    System.out.println("Bean with message '"  message  "' is going through init.");
}
  

Вы увидите, что все компоненты инициализируются при запуске и что сообщение, которое вы видите, на самом деле исходит от класса с методом init.

Если вы не хотите такого поведения, вы можете использовать отложенный инициализирующий:

 <bean id="helloWorld2" class="y.HelloWorld"
      init-method="init" destroy-method="destroy" lazy-init="true">