手动实现IOC
加载简单IOC容器分为四部分 1.加载xml文件,遍历其中标签 2.获取标签中的class,id,加载class属性对应的类,加载标签属性 3,利用反射遍历标签,加载属性值,填充到bean 4将bean注册到bean容器 firstIOC:IOC的实现类 firstIOCTest:IOC的测试类 Hero:测试类使用的bean Skill:属性 ioc.xml:bean配置文件
package IOC;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
public class firstIOC {
private Map<String,Object> beanMap=new HashMap<>();
public firstIOC(String location) throws Exception{
loadBean(location);
}
public Object getBean(String name){
Object bean=beanMap.get(name);
if(bean==null){
throw new IllegalArgumentException("there is no bean with name:"+name);
}
return bean;
}
private void loadBean(String location) throws Exception {
//加载xml配置文件
InputStream inputStream=new FileInputStream(location);
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder=factory.newDocumentBuilder();
Document document=documentBuilder.parse(inputStream);
Element root=document.getDocumentElement();
NodeList nodeList=root.getChildNodes();
//遍历bean标签
for (int i = 0; i <nodeList.getLength() ; i++) {
Node node=nodeList.item(i);
if(node instanceof Element){
Element element= (Element) node;
String id=element.getAttribute("id");
String className=element.getAttribute("class");
//加载beanClass
Class beanClass=null;
try{
beanClass=Class.forName(className);
}catch (Exception e){
e.printStackTrace();
return;
}
//创建bean
Object bean=beanClass.newInstance();
//遍历<propery>标签
NodeList propertyNodes=element.getElementsByTagName("property");
for(int j=0;j<propertyNodes.getLength();j++){
Node propertyNode=propertyNodes.item(j);
if(propertyNode instanceof Element){
Element propertyElement= (Element) propertyNode;
String name=propertyElement.getAttribute("name");
String value=propertyElement.getAttribute("value");
//利用反射将bean相关字段设置为可访问
Field declareField=bean.getClass().getDeclaredField(name);
declareField.setAccessible(true);
if(value!=null&&value.length()!=0){
//将属性字段填充到相关字段
declareField.set(bean,value);
}else{
String ref=propertyElement.getAttribute("ref");
if(ref==null||ref.length()==0){
throw new IllegalArgumentException("ref config error");
}
declareField.set(bean,getBean(ref));
}
//将bean注册到bean容器
registerBean(id,bean);
}
}
}
}
}
private void registerBean(String id, Object bean) {
beanMap.put(id,bean);
}
}
package IOC;
public class Hero {
private String name;
private String old;
private String height;
private String location;
private Skill skill;
}
package IOC;
public class Skill{
private String cd;
private String isR;
}
package IOC.ioc;
import IOC.Hero;
import IOC.Skill;
import IOC.firstIOC;
import org.junit.Test;
public class firstIOCTest {
@Test
public void getBean() throws Exception{
String location= firstIOC.class.getClassLoader().getResource("ioc.xml").getFile();
firstIOC firstIOC=new firstIOC(location);
Skill skill= (Skill) firstIOC.getBean("skill");
Hero hero=(Hero) firstIOC.getBean("hero");
System.out.println(skill);
System.out.println(hero);
}
}
<beans>
<bean id="skill" class="IOC.Skill">
<property name="cd" value="69s"/>
<property name="isR" value="is"/>
</bean>
<bean id="hero" class="IOC.Hero">
<property name="name" value="盖伦"/>
<property name="old" value="12"/>
<property name="height" value="222"/>
<property name="location" value="德玛西亚"/>
<property name="skill" ref="skill "/>
</bean>
</beans>