Действительно ли lazy-init работает так, как рекламируется?

#spring

#весна

Вопрос:

Согласно документации http://docs.spring.io/spring-framework/docs/3.2.2.RELEASE/spring-framework-reference/html/beans.html#beans-factory-lazy-init приведенное ниже не должно быть введено MyDatabase в действие, но я ясно вижу, что это имеет место в afterPropertiesSet методе HibernateDatabase класса при отладке. Если я удалю MyDatabaseEntityManagerFactory , этого не произойдет. Однако это не должно иметь значения, учитывая, что MyDatabaseEntityManagerFactory это также лениво — это не должно приводить MyDatabase к инициализации.

Либо я неправильно понимаю часть документов, в которых говорится, что ленивый компонент, ссылающийся на другой ленивый компонент, не должен вызывать его инициализацию, либо здесь есть фундаментальная проблема Spring. Может кто-нибудь пролить некоторый свет на это или, возможно, предложить альтернативу тому, чего я хочу достичь?

Спасибо.

 <?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:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd"
    default-lazy-init="false">
    <bean id="HibernateDatabase" class="mypackage.database.HibernateDatabase"
        abstract="true" />

    <bean id="MyDatabase" parent="HibernateDatabase" lazy-init="true">
        <property name="driver" value="com.sybase.jdbc3.jdbc.SybDriver" />
        <property name="dialect" value="org.hibernate.dialect.SybaseDialect" />
        <property name="url" value="${My.dburl}" />
        <property name="user" value="${My.dbuser}" />
        <property name="password" value="${My.dbpassword}" />
    </bean>

    <bean id="EntityManagerFactory" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"
        abstract="true">
        <property name="targetMethod" value="getEntityManagerFactory" />
    </bean>

    <bean id="MyDatabaseEntityManagerFactory" parent="EntityManagerFactory" lazy-init="true">
        <property name="targetObject" ref="MyDatabase" />
    </bean>
</beans>
 

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

1. Используете ли вы MyDatabaseEntityManagerFactory в качестве ссылки в другом компоненте?

2. Не в этом случае — это в основном определение утилиты, и приложения, которым требуется ссылка на DB, будут ссылаться на объекты по мере необходимости, но в противном случае импорт этого XML не должен иметь никакого эффекта. К этому вопросу привел тот факт, что он устанавливал их в приложении, где мне не нужна была база данных. Удаление определения доказало, что на него ничего не ссылается (в противном случае Spring жаловался бы на отсутствие ссылок).

3. Думаю, было бы полезно узнать, почему Spring считает, что ему нужно создать экземпляр компонента. Можете ли вы поместить Spring в журнал отладки, чтобы мы могли видеть, какую зависимость он пытается удовлетворить, и, следовательно, почему он создает компонент?

4. Я думаю, что это может быть так, как это происходит прямо перед вызовом afterPropertiesSet(): org.springframework.beans.factory.support . DefaultListableBeanFactory с нетерпением кэширует компонент ‘MyDatabase’, чтобы разрешить возможные циклические ссылки

5. Чтобы определить, что часть импорта не несет ответственности, я переместил определение в свой основной Spring для приведенных выше определений базы данных. Единственное, что, кажется, имеет значение, это то, определяю ли я MyDatabaseEntityManagerFactory или нет. Если я этого не сделаю, то я в основном не получаю никаких отладочных журналов о MkvDatabase, кроме того, что он указан в синглетах с предварительным созданием экземпляров (хотя из кода, который, похоже, не заботится ни о чем из этого и просто перечисляет все определения).