Spring bean объекты destroy-method, singleton и prototype - программирование
Подтвердить что ты не робот

Spring bean объекты destroy-method, singleton и prototype

Я новичок в структуре spring, начал с некоторых уроков, чтобы узнать его.

У меня есть следующие файлы,

# MainProgram.java

package test.spring;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainProgram {
        public static void main(String[] args) {
              AbstractApplicationContext context = 
                              new ClassPathXmlApplicationContext("Bean.xml");     
              HelloSpring obj = (HelloSpring) context.getBean("helloSpring");
              obj.setMessage("My message");
              obj.getMessage();
              context.registerShutdownHook();

        }
 }

# HelloSpring.java

package test.spring;

public class HelloSpring   {
     private String message;

     public void setMessage(String message){
      this.message  = message;
      System.out.println("Inside setMessage");
   }

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

   public void xmlInit() {
    System.out.println("xml configured  initialize");
   } 

    public void xmlDestroy() {
    System.out.println("xml configured destroy");
    }

  }

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

     <bean id="helloSpring" class="test.spring.HelloSpring" 
          scope="prototype" init-method="xmlInit" destroy-method="xmlDestroy">

     </bean>
     </beans>

Когда я беру scope="singleton", мой вывод:

 xml configured  initialize
 Inside setMessage
 Your Message : My message
 xml configured destroy

Когда я беру scope="prototype", мой вывод:

 xml configured  initialize
 Inside setMessage
 Your Message : My message

xmlDestroy() метод вызывается с помощью singleton scope bean, но не с prototype любезно помогите мне в следующем,

Это правильно? если да, то каковы были бы возможные причины?

Также у меня есть некоторые запросы, например

какая разница или связь между ApplicationContext , AbstractApplicationContext and ClassPathXmlApplicationContext

4b9b3361

Ответ 1

xmlDestroy() метод вызывается с областью Singleton bean, но не с прототипом, потому что

Spring не управляет полным жизненным циклом прототипа bean: контейнер создает, настраивает, украшает и иным образом собирает прототип объекта, передает его клиенту, а затем больше не знает об этом экземпляре прототипа. Для освобождения ресурсов попробуйте реализовать пользовательский почтовый процессор bean.

В отличие от singleton beans, где контейнер spring управляет полным жизненным циклом

Вы можете посмотреть этот базовый учебник для различий между различными контекстами

Обратитесь документация

Ответ 2

Синтаксис bean означает, что в контексте приложения есть только один экземпляр этого bean. Это означает, что вы делаете что-то вроде этого:

HelloSpring obj = (HelloSpring) context.getBean("helloSpring");
    obj.setMessage("My message");
    System.out.printIn(obj.getMessage());
    HelloSpring anotherObj = (HelloSpring) context.getBean("helloSpring");
    System.out.printIn(anotherObj.getMessage());

Вы увидите сообщение "Мое сообщение" на выходе консоли дважды.

Для прототипа beans каждый раз, когда вы пытаетесь получить один из них из контекста приложения, вы получите новый экземпляр, поэтому, если вы снова запустите указанный выше код, второй вывод консоли будет "null".

Поскольку нет необходимости в том, чтобы контейнер вызывал метод destroy для прототипа bean, это не так, и поведение корректно.

Разница между указанными классами заключается в том, что они являются интерфейсом, абстрактным классом и конкретным классом соответственно, чтобы лучше понять эти концепции, я предлагаю прочитать официальную документацию оракула для java здесь Учебники Oracle Java.

Ответ 3

Это ожидаемое поведение. Неизвестно, когда Spring узнает, когда вы закончили использовать область прототипа bean, поэтому уничтожение bean не управляется Spring для прототипа scope beans. Из документации:

Хотя методы обратного вызова жизненного цикла инициализации вызывают на всех объекты независимо от области действия, в случае прототипов, настроены обратные вызовы жизненного цикла разрушения не вызываются.

Дополнительную информацию см. в Spring документации.

Что касается ApplicationContext s, вы можете выбрать тот, который лучше всего подходит для вашего приложения. Это зависит от того, хотите ли вы использовать конфигурацию XML или аннотации bean и, например, используете ли вы в контейнере сервлетов. ApplicationContext сам по себе является интерфейсом в корне типа иерархии.

Ответ 4

ваше приложение может запросить новые экземпляры прототипа beans каждые 10 миллисекунд, сделать что-то с помощью bean, а затем выпустить его из области видимости. Если Spring должен был уничтожить() их при закрытии приложения, он должен был бы ссылаться на каждый созданный прототип bean, предотвращая их сбор мусора и, таким образом, вызывая утечку памяти.

Ответ 5

Я также попытался получить событие destroy bean, область видимости которого "prototype". Поэтому я прочитал все ответы выше и попробую их ответы. В результате я догадываюсь, что невозможно обнаружить уничтожение даже прототипа bean.

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

см. здесь (https://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/beans.html#beans-factory-scopes-prototype)

Ответ 6

Пожалуйста, проверьте свой тип области действия в конфигурационном файле spring. Если scope = "prototype", то измените его на scope = "singleton"

<bean id="helloWorld" class="com.example.test.HelloWorld"
init-method="init" destroy-method="destroy">
<property name="message" value="Hello World!" />