Spring作为经典的框架,作为java程序员多多少少对其源码会一定的了解,今天将对Spring IOC进行实现
1.实现需要以下
- junit单元测试,如有疑问请稳步java junit测试
- dom4j.jar对xml的解析,如有疑问请稳步使用dom4j.jar操作XML
- 反射与内省
- 类型的自动转换
2.需要解析的spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean name="a" class="zx.mes.hyl.bean.A">
<property name="name" value="张三"></property>
<property name="age" value="33"></property>
</bean>
<bean name="b" class="zx.mes.hyl.bean.B">
<property name="name" value="李四"></property>
<property name="a" ref="a"></property>
</bean>
</beans>
3流程步骤
4.config容器,从spring.xml中解析
public class ConfigManager {
private static Map<String,Bean> config=new HashMap<String, Bean>();
public static Map<String,Bean> getConfig(String path){
//读取spring.xml
SAXReader reader=new SAXReader();
Document document=null;
try {
document=reader.read(ConfigManager.class.getResourceAsStream(path));
} catch (DocumentException e) {
e.printStackTrace();
throw new RuntimeException("配置文件路径有问题,请检查");
}
//解析出bean
String xpath="//bean";
List<Element> eleBeans=document.selectNodes(xpath);
if (eleBeans!=null) {
for (Element eleBean : eleBeans) {
Bean bean=new Bean();
String name=eleBean.attributeValue("name");
String className=eleBean.attributeValue("class");
List<Element> properties= eleBean.elements("property");
for (Element eleProp : properties) {
Property property=new Property();
property.setName(eleProp.attributeValue("name"));
property.setRef(eleProp.attributeValue("ref"));
property.setValue(eleProp.attributeValue("value"));
bean.getProperties().add(property);
}
bean.setName(name);
bean.setClassName(className);
config.put(name, bean);
}
}
//添加到config中
return config;
}
}
5.context容器的实现
6.相应的步骤的重要代码
public ClassPathXmlApplicationContext(String path){
//初使化config
Map<String, Bean> config=ConfigManager.getConfig(path);
//初使化工厂 contex
for (Entry<String, Bean> en : config.entrySet()) {
String beanName=en.getKey();
Bean b=en.getValue();
//反射创建对象
Object obj=null;
try {
if (!isExitBean(b.getName())) {
obj = createBean(b);
context.put(beanName, obj);
}else{
obj=context.get(b.getName());
}
//分两种:
if (b.getProperties()!=null) {
for (Property prop : b.getProperties()) {
String name=prop.getName();
String value=prop.getValue();
//1.值是value
if (value!=null && !"".equals(value)) {
//使用BeanUtils工具方法完成属性的注入//自动完成类型转换
Map<String, String[]> paramMap=new HashMap<String,String[]>();
paramMap.put(name, new String[]{value});
org.apache.commons.beanutils.BeanUtils.populate(obj, paramMap);
//Method mSetName=BeanUtils.getWriteMethod(name,clazz);
//mSetName.invoke(obj, value);
}
String ref=prop.getRef();
//2.值是ref类型
if (ref!=null) {
if (! isExitBean(ref)) {
Object obj2=Class.forName(config.get(ref).getClassName()).newInstance();
context.put(ref, obj2);
}
Method mSetRef=BeanUtils.getWriteMethod(name, obj.getClass());
mSetRef.invoke(obj, context.get(ref));
}
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("bean class="+b.getClassName()+"有问题,请检查"+",或者无空构造");
throw new RuntimeException("bean class="+b.getClassName()+"有问题,请检查"+",或者无空构造");
}
}
}