3

应用程序上下文的原型部分:

<bean id="option_A" class="class_a" lazy-init="true"/>
<bean id="option_B" class="class_b" lazy-init="true" depends-on="setup_bean"/>
<alias name="option_${OPTION_PROPERTY}" alias="thingChosen"/>
<bean id="setup_bean" class="class_setup" lazy-init="true"/>

这里的概念是,如果 OPTION_PROPERTY 设置为“A”,那么

<bean id="foo" class="whatever"><property name="bar" ref="thingChosen"/></bean>

将获得一个注入到 bar 属性的 class_a 实例,如果该属性设置为“B”,那么它将获得一个注入的 b 类实例,但 b 类对 setup_bean 有一个隐藏的依赖(a 类缺少),所以 setup_bean 必须首先创建。

发生的情况是,如果 OPTION_PROPERTY 设置为“A”,则仍会创建 setup_bean。我已经使用 Spring 3.2.4.RELEASE 尝试过这个,并且它是一致的。这似乎是我的错误或误解。

如果一个 bean 是惰性初始化的,那么依赖 bean 是否不应该等到该 bean 被惰性创建后再自己创建?

4

2 回答 2

2

如果一个 bean 是惰性初始化的,那么依赖 bean 是否不应该等到该 bean 被惰性创建后再自己创建?

是的。换句话说,在被请求和初始化option_B之前不会被创建。setup_bean如果option_B首先请求,则将强制setup_bean首先初始化。

文件说

但是,当延迟初始化的 bean 是未延迟初始化的单例 bean 的依赖项时,ApplicationContext 会在启动时创建延迟初始化的 bean,因为它必须满足单例的依赖项。

因此,这个 bean 声明

<bean id="foo" class="whatever"><property name="bar" ref="thingChosen"/></bean>

将强制初始化thingChosen,在这种情况下是别名option_A

我无法重现您正在经历的事情(也不应该)。仔细检查你在做什么。也许另一个 bean 正在引用setup_bean.

这是一个SSCCE

public class Test {
    public static void main(String[] args) throws Exception {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        System.out.println("context initialized");
        context.getBean("shouldnot");
    }
    public static class MyClass {
        public MyClass() {
            System.out.println("myclass");
        }
    }   
    public static class SetupBean {
        public SetupBean() {
            System.out.println("setup");
        }
    }
    public static class MyOtherClass {
        private MyClass myClass;
        public MyOtherClass() {
            System.out.println("myotherclass");
        }
        public MyClass getMyClass() {
            return myClass;
        }
        public void setMyClass(MyClass myClass) {
            this.myClass = myClass;
        }
    }
}

spring.xml豆子

<bean id="myref" class="test.Test$MyClass" lazy-init="true"></bean>
<bean id="shouldnot" class="test.Test$MyClass" lazy-init="true" depends-on="setup_bean"></bean>

<bean class="test.Test$MyOtherClass" >
    <property name="myClass" ref="myref"></property>
</bean>

<bean id="setup_bean" class="test.Test$SetupBean" lazy-init="true"></bean>

它打印(减去 Spring 日志)

myotherclass
myclass
context initialized
setup
myclass

换句话说,setup仅在shouldnot被请求时创建。

于 2013-10-11T20:07:51.697 回答
0

事实证明,在上下文的其他地方,有这个小宝石:

<context:annotation-config />

看来,这会导致惰性初始化被忽略。

下一步是试图弄清楚排除机制是如何工作的,但这超出了这个问题的范围。

于 2013-10-11T21:58:14.283 回答