20140314 一起学Spring Framework 003 引用属性的装配

前面两篇是最简单的通过反射创建实例和简单赋值功能的实现,这篇的任务是能装配引用类型的属性。

<?xml version="1.0" encoding="UTF-8"?>
<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.2.xsd">
	<bean id="gordon" class="gordon.study.spring.sample.Employee">
		<property name="name" value="Gordon" />
		<property name="age" value="32" />
		<property name="male" value="true" />
		<property name="birthday" value="1982-07-05" />
		<property name="salary" value="817.52" />
		<property name="dept" ref="lab" />
	</bean>
	<bean id="ghost" class="gordon.study.spring.sample.Employee">
		<property name="name" value="Ghost" />
		<property name="dept" ref="warehouse" />
	</bean>
	<bean id="elf" class="gordon.study.spring.sample.Employee">
		<property name="name" value="Elf" />
		<property name="dept" ref="lab" />
	</bean>
	<bean id="robot" class="gordon.study.spring.sample.Employee"
		scope="prototype">
		<property name="name" value="Robot" />
		<property name="dept" ref="warehouse" />
	</bean>
	<bean id="lab" class="gordon.study.spring.sample.Department">
		<property name="name" value="Research Lab" />
	</bean>
	<bean id="warehouse" class="gordon.study.spring.sample.Department">
		<property name="name" value="Warehouse" />
	</bean>
</beans>

测试改为junit4

public class Test001 extends TestCase {

	public void testSample1() {
		try {
			ApplicationContext context = new ClassPathXmlApplicationContext("sample1.xml");
			Employee gordon = (Employee) context.getBean("gordon");
			Employee elf = (Employee) context.getBean("elf");
			Employee ghost = (Employee) context.getBean("ghost");
			Department lab = (Department) context.getBean("lab");
			Department warehouse = (Department) context.getBean("warehouse");
			Employee robot1 = (Employee) context.getBean("robot");
			robot1.setName("Robot1");
			Employee robot2 = (Employee) context.getBean("robot");
			robot2.setName("Robot2");

			assertEquals("Gordon", gordon.getName());
			assertEquals(32, gordon.getAge());
			assertEquals(817.52f, gordon.getSalary());
			assertEquals(true, gordon.isMale());
			
			assertTrue(gordon != elf);
			assertTrue(gordon.getDept() == elf.getDept());
			assertTrue(gordon.getDept() == lab);
			assertTrue(gordon.getDept() != ghost.getDept());
			assertTrue(robot1 != robot2);
			assertTrue(robot1.getDept() == robot2.getDept());
			assertTrue(robot1.getDept() == warehouse);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}


开始解决。
首先,BeanProperty类要加上propertyRef字段,xml reader做相应修改。

接着考虑装配引用属性的问题。当mySpring使用者调用getBean时,我们是先初始化一个实例,然后再装配其属性。当装配引用类型的属性时,可能会发现beans这个map里面还没有可用的实例(可能是singleton的尚未初始化,也可能是prototype类型的所以不放入beans),这时容器就得对该引用类型调用getBean,以期望它返回一个可供自己装配的实例。一个典型的递归。


	@Override
	public Object getBean(String beanName) throws Exception {
		if (beans.containsKey(beanName)) {
			return beans.get(beanName);
		}

		Object bean = createBean(beanName);

		if (beanDefinitions.get(beanName).getScope() == 0) {
			beans.put(beanName, bean);
		}

		assembleBean(beanName, bean);

		return bean;
	}

	private void assembleBean(String beanName, Object targetBean) throws Exception {
		BeanDefinition beanDef = beanDefinitions.get(beanName);
		Method[] methods = targetBean.getClass().getMethods();
		for (BeanProperty prop : beanDef.getProperties()) {
			String beanRef = prop.getPropertyRef();
			if (beanRef != null && beanRef.length() > 0) {

				Object refBean = getBean(beanRef);

				Method setterMethod = findSetterMethod(methods, targetBean.getClass(), prop.getPropertyName());
				setterMethod.invoke(targetBean, refBean);
			}
		}
	}








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值