Spring——实现一个容器

长篇大论

需求

xml的ioc容器,单例,set注入。

简单类型的转换,
引用类型的套娃。

实现思路

  • 核心对象:Map
  • 创建容器:
    扫描配置文件,转为BeanInfo数组
    遍历BeanInfo,创建各个对象,注入简单类型。
    遍历BeanInfo,注入引用类型。
  • 获取对象:Map.get(xxx)

用到的API

  • 反射
  • xml解析

效果展示

实体类

public class Student {
	private String name;
	private Integer age;
	private Student bestFriend;
	//空参构造,各种getset,toString
}

xml

<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean id="s1" class="base.ioc.test.entity.Student">
        <property name="name" value="张三"/>
        <property name="age" value="23"/>

        <property name="bestFriend" ref="s2"/>
    </bean>
    <bean id="s2" class="base.ioc.test.entity.Student">
        <property name="name" value="李四"/>
        <property name="age" value="32"/>
    </bean>
</beans>

测试类

@Test
public void fun3() {
	XMLContainer container = new XMLContainer("beans.xml");
	System.out.println(container.getBean("s1"));
	System.out.println(container.getBean("s2"));
}

测试结果

Spring——实现一个容器

核心容器

一个简单的接口

public interface Container {
	Object getBean(String id);
}

一个简单的实现

public class XMLContainer implements Container {
	private static final Map<String, Object> data = new ConcurrentHashMap<>();

	public XMLContainer(String xmlPath) {
		//解析xml
		List<BeanInfo> beanInfos = XmlUtil.parse(xmlPath);
		//创建对象,注入简单类型
		for (BeanInfo info : beanInfos) {
			data.put(info.getName(), ReflectUtil.createObj(info));
		}
		//注入引用类型
		for (BeanInfo info : beanInfos) {
			ReflectUtil.initRefs(info, data);
		}
	}

	@Override
	public Object getBean(String id) {
		return data.get(id);
	}
}

BeanInfo的结构

public class BeanInfo {
	private String name;
	private Class targetClass;
	private Map<String, String> values = new ConcurrentHashMap<>();
	private Map<String, String> refs = new ConcurrentHashMap<>();
	
	//空参构造,各种setget,toString
}

XML解析相关

反射相关

上一篇:常见yaml写法-pod


下一篇:【高德地图API】从零开始学高德JS API(一)地图展现——仙剑地图,麻点图,街景,室内图