Spring IoC:depends-on覆盖了lazy-init

时间:2013-10-11 17:35:57

标签: java spring

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

<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>

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

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

如果bean是lazy-init,那么不应该依赖于bean等待,直到该bean在创建之前被懒惰地创建?

2 个答案:

答案 0 :(得分:2)

  

如果bean是lazy-init,那么不应该依赖于bean等待直到   那个bean在创建之前是懒惰创建的吗?

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

The documentation says

  

但是,当懒惰初始化的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

<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时创建。

答案 1 :(得分:0)

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

<context:annotation-config />

这看起来会导致lazy-init被忽略。

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