Spring IoC контейнер: настройка бинов, методы инициализации и уничтожения по умолчанию

Когда вы пишете методы обратных вызовов инициализации и уничтожения, которые не используют специфичные для Spring интерфейсы обратного вызова InitializingBean и DisposableBean, вы обычно пишете методы с именами, такими как init(), initialize(), dispose() и так далее. В идеале имена таких методов обратного вызова жизненного цикла стандартизируются по всему проекту, чтобы все разработчики использовали одинаковые имена методов и обеспечивали согласованность.

Вы можете настроить контейнер Spring на "поиск" именованных методов обратного вызова инициализации и уничтожения на каждом бине. Это означает, что вы, как разработчик приложения, можете написать свои классы приложения и использовать обратный вызов инициализации, называемый init(), без необходимости настраивать атрибут init-method="init" для каждого определения компонента. Контейнер Spring IoC вызывает этот метод при создании компонента (и в соответствии со стандартным контрактом обратного вызова жизненного цикла, описанным ранее). Эта функция также обеспечивает согласованность в именах для методов обратного вызова инициализации и уничтожения.

Предположим, что ваши методы обратного вызова инициализации называются init(), а методы обратного вызова уничтожения - destroy(). Ваш класс тогда похож на класс в следующем примере:

Java

public class DefaultBlogService implements BlogService {

    private BlogDao blogDao;

    public void setBlogDao(BlogDao blogDao) {
        this.blogDao = blogDao;
    }

    //  это метод обратного вызова инициализации
    public void init() {
        if (this.blogDao == null) {
            throw new IllegalStateException("The [blogDao] property must be set.");
        }
    }
}

Kotlin

class DefaultBlogService : BlogService {

    private var blogDao: BlogDao? = null

    // это метод обратного вызова инициализации
    fun init() {
        if (blogDao == null) {
            throw IllegalStateException("The [blogDao] property must be set.")
        }
    }
}

Затем вы можете использовать этот класс в bean-компоненте, напоминающем следующее:

<beans default-init-method="init">

    <bean id="blogService" class="com.something.DefaultBlogService">
        <property name="blogDao" ref="blogDao" />
    </bean>

</beans>

Наличие атрибута default-init-method в атрибуте элемента верхнего уровня <beans/> приводит к тому, что контейнер IoC Spring распознает метод с именем init в классе компонента в качестве метода обратного вызова инициализации. Когда бин создается и собирается, если у класса бина есть такой метод, он вызывается в соответствующее время.

Аналогичным образом можно настроить обратные вызовы метода уничтожения (то есть в XML), используя атрибут default-destroy-method в элементе верхнего уровня <beans/>.

Если в существующих классах бинов уже есть методы обратного вызова, имена которых расходятся с соглашением, вы можете переопределить значение по умолчанию, указав (в XML) имя метода, используя атрибуты init-method и destroy-method в самом <bean/>.

Контейнер Spring гарантирует, что сконфигурированный обратный вызов инициализации вызывается сразу после того, как компонент передается со всеми зависимостями. Таким образом, обратный вызов инициализации вызывается для необработанной ссылки на компонент, что означает, что перехватчики AOP и т. д. еще не применены к компоненту. Сначала создается целевой бин, а затем применяется прокси AOP (например) с цепочкой перехватчиков. Если целевой компонент и прокси определяются отдельно, ваш код может даже взаимодействовать с необработанным целевым компонентом, минуя прокси. Следовательно, было бы непоследовательным применять перехватчики к методу init, потому что это связывало бы жизненный цикл целевого компонента с его прокси или перехватчиками и оставляло бы странную семантику, когда ваш код взаимодействует напрямую с необработанным целевым компонентом.


Читайте также:


Комментарии

Популярные сообщения из этого блога

Методы класса Object в Java

Как получить текущий timestamp в Java

Основные опции JVM для повышения производительности и отладки