目前为止,我们只为 bean 注入固定属性变量,但是如果一个 Bean 的属性变量是另一个 Bean,那要怎么做?
做法一:1. 先创建 Bean,再为 Bean 注入属性 2. 在注入属性为 Bean 的时候,如果 Bean 没有被创建,则对此 Bean 重复 1)步骤。 因为都是先创建 Bean 再注入属性,所以不可能出现死循环状态。
做法二: 1. 将所有的 Bean 都先创建(不注入属性)2. 再做注入属性操作
做法一使用的是懒加载,做法二使用的是先创建后注入。以下以做法一为例。
1. 要定义 Bean 作为属性,我们需要定义一个 BeanReference
,用来表示这个属性是一个 Bean 的引用。
public class BeanReference {
private String name;
private Object bean;
public BeanReference(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object getBean() {
return bean;
}
public void setBean(Object bean) {
this.bean = bean;
}
}
2. 依照做法一,在 AutowireCapableBeanFactory
初始化到为 Bean 属性的时候,获取/创建该 Bean
for (PropertyValue propertyValue : mbd.getPropertyValues().getPropertyValues()) {
Field declaredField = bean.getClass().getDeclaredField(propertyValue.getName());
declaredField.setAccessible(true);
Object value = propertyValue.getValue();
if (value instanceof BeanReference) {
BeanReference beanReference = (BeanReference) value;
value = getBean(beanReference.getName()); // 获取/创建该Bean
}
declaredField.set(bean, value);
}
3. 测试代码
@Test
public void testLazy() throws Exception {
// 1.读取配置
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(new ResourceLoader());
xmlBeanDefinitionReader.loadBeanDefinitions("tinyioc.xml");
// 2.初始化BeanFactory并注册bean
AbstractBeanFactory beanFactory = new AutowireCapableBeanFactory();
for (Map.Entry<String, BeanDefinition> beanDefinitionEntry : xmlBeanDefinitionReader.getRegistry().entrySet()) {
beanFactory.registerBeanDefinition(beanDefinitionEntry.getKey(), beanDefinitionEntry.getValue());
}
// 3.获取bean
HelloWorldService helloWorldService = (HelloWorldService) beanFactory.getBean("helloWorldService");
helloWorldService.helloWorld();
}
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于