Spring 文档描述了由 Ioc 容器管理的 beans 默认情况下是隐式预实例化的,而不是将它们指定为延迟初始化。我定义了一个子 bean 定义 A,它从其父 bean 定义 B 继承配置数据。它们都在元素上指定了一个属性。然后我通过Ioc容器检索了bean A的实例,发现Ioc容器只是调用了bean A的初始化方法。为什么Ioc容器没有调用启动时实例化的bean B的初始化方法?
<bean id="student" class="com.ford.spring.pojo.Student" lazy-init="true" init-method="init">
<property name="age" value="20"/>
<property name="gender" value="male"/>
<property name="name" value="porro"/>
<property name="id" value="1"/>
</bean>
<bean id="player"
class="com.ford.spring.pojo.Player"
parent="student" init-method="init" destroy-method="destroy">
<property name="nationality" value="Italy"/>
</bean>
ConfigurableApplicationContext applicationContext = new ClassPathXmlApplicationContext("config-metadata.xml");
Player player = (Player) applicationContext.getBean("player");
applicationContext.close();
System.out.println(player);
为什么Ioc容器没有调用启动时实例化的Bean B的初始化方法?
根据这个:
子 bean 定义继承范围、构造函数参数值、 属性值和方法从父级覆盖,带有选项 添加新值。 任何作用域,初始化方法,销毁方法, 或您指定的静态工厂方法设置覆盖 对应的父级设置。
因此,首先,只有当子 bean 的
init-method
与父 bean 不同时,配置子 bean 的 init-method
才有意义。如果子bean和父bean都有相同的init-method
,则不需要在子bean上配置init-method
。
其次,它只配置bean的初始化方法。每个 bean 只能有一种初始化方法。初始化方法是否执行其父初始化方法是其实现细节,从bean定义的角度来看,它并不关心它。它只关心你告诉它初始化方法是什么,这样它就会在创建一个 bean 实例后简单地执行它,就是这样。
因此,如果您希望
Player
的初始化方法执行其父级的 init。方法,你可以将其实现为:
public class Player extends Student{
void init(){
super.init();
//do other player initialisation codes here..
}
}
另一方面,如果您不希望其初始化方法执行其父级的 init。方法,你可以将其实现为:
public class Player extends Student{
void init(){
//do player initialisation codes here..
}
}