我有一个关于spring beans初始化的问题。当我们通过init方法填充bean属性时,scneario会是什么?看看下面给出的代码片段。这里我通过init方法填充超类bean属性列表。
1)超级Bean:
public class Super {
private List<String> list = new ArrayList<String>();
public void setList(List<String> list) {
this.list = list;
}
public void init(){
System.out.println("Super init called");
populateList();
System.out.println("Super list"+list.size());
}
public void populateList(){
list.add("A");
list.add("B");
}
public List<String> getList() {
return list;
}
}
2)Bean 2:
public class Sub extends Super {
public static void main(String[] args) {
ApplicationContext ctx = new FileSystemXmlApplicationContext("conf/appXml/init-test.xml");
Sub utils = (Sub)ctx.getBean("sub");
System.out.println("Sub list:::"+utils.getList().size());
for(String s : utils.getList()){
System.out.println("Value::::" +s);
}
}
}
3)Spring-context xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id = "super" class = "com.hitesh.springtest.Super" init-method="init">
</bean>
<bean id = "sub" class = "com.hitesh.springtest.Sub"></bean>
</beans>
4)输出: 超级初始化了 超级列表2 子列表::: 0
我的问题是当超级容器被容器初始化时,会调用init()。在此方法中,将填充列表对象。现在,当子类实例化完成时,为什么我们将列表大小设置为0,因为我们指的是在超级bean初始化中填充的非常相同的列表对象。有人可以解释一下吗?
答案 0 :(得分:3)
不是very same list object
。您的上下文中有两个对象:super
和sub
。由于list
是一个实例字段,因此存在list
个对象的两个实例,一个用于super
,另一个用于sub
。 sub
的那个从未初始化,因为没有为该bean设置init-method
。
答案 1 :(得分:1)
让我们说,而不是spring,你正在初始化对象(松散地在弹簧容器的行上),代码看起来像这样
Super super = new Super();
super.init();
Sub sub = new Sub();
//now if you say
sub.getList().size();
//This will always print size zero as you never initialized the super class collection.
所以有两个不同的对象。如果超类被定义为另一个 bean,则它不会继承超类的属性。
答案 2 :(得分:0)
您会看到“超级列表2”,因为Spring正在使用bean
创建id = "super"
,并且当init-method
按照Spring-context.xml
中的定义创建bean id = "sub"
时,它会调用init-method
。
当Spring创建init-method
时,它不会调用sub
,因为没有指定。{1}}如果将{{1}}添加到{{1}} bean的定义中,您应该会看到您期望的行为。