Весна - Как я могу уничтожить мои бобы прототипа? - PullRequest
15 голосов
/ 23 декабря 2011

У меня есть одноэлементный компонент, у которого есть метод, который создает экземпляры прототипа компонента.Я использую метод , описанный здесь , чтобы получить экземпляры bean-компонента прототипа.

public class SingletonService implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    public void go() {

        MyPrototypeBean prototype = applicationContext
            .getBean(MyPrototypeBean.class);

        prototype.doSomething();
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
        throws BeansException {

        this.applicationContext = applicationContext;
    }
}

Сначала я подумал, что это достаточно хорошо, что мой экземпляр 'prototype' пойдетвыходит из области видимости при возврате метода go, что означает, что экземпляр не имеет ссылки и будет собирать мусор.

Однако одноранговый узел указал на следующее утверждение из документации :

Код клиента должен очистить объекты в области прототипа и освободить дорогостоящие ресурсы, которые содержатся в прототипе.

Похоже, что Spring сохранитссылка, и поэтому gc никогда не поднимет его?Если это так, как я могу сказать Spring, чтобы выпустить ссылку?В документации упоминается, что я могу использовать «настраиваемый постпроцессор bean-компонента», но не ясно, куда этот процессор будет вписываться и какой код он будет запускать.

Спасибо всем заранее за помощь, Рой

Ответы [ 2 ]

11 голосов
/ 23 декабря 2011

Я думаю, вы неправильно понимаете документацию. Просто говорится, что Spring не будет управлять жизненным циклом прототипа bean-компонента, поэтому методы @PreDestroy (и т. Д.) Должны вызываться вашим собственным кодом. Весна не сохранит ссылку.

0 голосов
/ 07 августа 2018

Просто для большей ясности в ответе artbristol выше: artbristol правильный. Spring создаст bean-компонент-прототип, требуемый вашим кодом, но не уничтожит его. Такое поведение разработано, поскольку считается, что более эффективно разрешить сборщику мусора «подобрать» вашу зависимость от прототипа, как только она выйдет из области видимости. Если это не было сделано таким образом, то единственной альтернативой для контейнера Spring было бы сохранение ссылки на каждый экземпляр вашего прототипа bean-компонента при его создании. Учитывая, что ваш код создает новый экземпляр компонента MyPrototypeBean каждый раз, когда он вызывается, это означает, что вы можете создать слишком много экземпляров MyPrototypeBean, собирая, но не уничтожая, поскольку уничтожение происходит только при закрытии контейнера Spring. Вы можете понять, что это может очень легко привести к быстрой утечке памяти.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...