Spring IOC的简单实现
程序员文章站
2022-07-12 12:57:28
...
控制反转IOC(Inverse Of Control),又称为依赖注入DI(Denpendency Injection),指的是从不同的角度的描述的同一件事情,就是指通过引入IOC容器,利用依赖关系注入的方式,实现对象之间的解耦。IOC是基于工厂模式和反射实现的。
简单IOC的实现步骤
实体类对象
public class car {
private String name;
private String length;
private String width;
private String height;
private Wheel wheel;
//get,set方法以及toString方法
}
public class Wheel {
private String brand;
private String specification;
//get,set方法以及toString方法
}
XML配置文件
<beans xmlns="http://www.springframework.org/schema/beans">
<bean id="wheel" class="com.xxx.iocDemo.vo.Wheel">
<property name="brand" value="Michelin"></property>
<property name="specification" value="265/60 R18"></property>
</bean>
<bean id="car" class="com.xxx.iocDemo.vo.car">
<property name="name" value="Mercedes benz G 500"></property>
<property name="length" value="4717mm"></property>
<property name="width" value="1855mm"></property>
<property name="height" value="1949mm"></property>
<property name="wheel" ref="wheel"></property>
</bean>
</beans>
Spring 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 simpleIOC {
private Map<String,Object> beanMap=new HashMap<>();//存放
/**
* 有参构造器
* @param location
*/
public simpleIOC(String location)throws Exception{
loadBeans(location);//到指定的地址中加载Bean对象
}
/**
* 根据Bean对象的名字获取到对象
* @param name
* @return
*/
public Object getBean(String name){
Object bean=beanMap.get(name);//到map中去获取
if(bean==null){
throw new IllegalArgumentException("there is no bean with name"+name);
}
return bean;
}
private void loadBeans(String location) throws Exception {
//加载xml文件
InputStream inputStream=new FileInputStream(location);
//创建DOM解析器的工厂
DocumentBuilderFactory documentBuilderFactory=DocumentBuilderFactory.newInstance();
//创建DOM模式的解析器
DocumentBuilder documentBuilder=documentBuilderFactory.newDocumentBuilder();
Document doc=documentBuilder.parse(inputStream);
//获取到根节点
Element root=doc.getDocumentElement();
//获取到根节点的子节点集合
NodeList nodes=root.getChildNodes();
//遍历集合,找到对应的子节点
for (int i = 0; i < nodes.getLength(); i++) {
Node node=nodes.item(i);
if(node instanceof Element){
Element ele=(Element) node;
String id=ele.getAttribute("id");
String className=ele.getAttribute("class");
//加载beanClass
Class beanClass=null;
try{
//反射第一步,获取到Class对象
beanClass=Class.forName(className);
}catch (ClassNotFoundException e){
e.printStackTrace();
return;
}
//反射第二步,创建对象实例,创建bean
//例如Wheel{brand='null', specification='null'}
Object bean=beanClass.newInstance();
//反射第三步,获取到对应对象属性的具体信息
// 遍历<Property>标签,实现将
NodeList propertyNodes=ele.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 declaredField=bean.getClass().getDeclaredField(name);
declaredField.setAccessible(true);
if(value!=null&&value.length()>0){
//将属性值填充到相关字段中
declaredField.set(bean,value);
}else{
String ref=propertyElement.getAttribute("ref");
if(ref==null||ref.length()==0){
throw new IllegalArgumentException("ref config error");
}
//将引用填充到相关字段
declaredField.set(bean,getBean(ref));
}
//将bean注册到bean容器中
registerBean(id,bean);
}
}
}
}
}
/**
* 将bean对象放到bean容器中
* @param id
* @param bean
*/
private void registerBean(String id,Object bean){
beanMap.put(id,bean);
}
}
调用
import org.junit.Test;
public class SimpleIOCTest {
@Test
public void getBean()throws Exception{
ClassLoader classLoader= simpleIOC.class.getClassLoader();
String location=classLoader.getResource("ioc.xml").getFile();
simpleIOC bf=new simpleIOC(location);
Wheel wheel=(Wheel) bf.getBean("wheel");
System.out.println(wheel);
car c=(car)bf.getBean("car");
System.out.println(c);
}
}