简单IOC容器实现

本文通过介绍如何实现一个简单的IOC容器,帮助读者深入理解控制反转的思想。内容包括步骤分析,如加载配置文件、依赖注入等关键环节,以及具体的容器实现类和测试过程。在测试中,展示了容器成功创建和注入对象的实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作为spring框架中的重要思想,ioc(控制反转)是面试中的常客。关于如何理解ioc容器,可以通过自己实现一个简单的ioc容器来领会

步骤分析

简单来说,ioc就是实现了通过配置文件创建对象功能,核心部分就是依赖注入,实现步骤如下:

  1. 加载配置文件
  2. 遍历bean标签,获取id和class值
  3. 加载class类并创建bean
  4. 遍历 < property > 标签,把属性值填充到相关字段
  5. 把bean注册到容器当中

IOC容器实现类

直接看代码和注释:

private Map<String, Object> beanmap = new HashMap<String, Object>();    
public IOCDemo(String location) throws Exception {
  loadBeans(location); 
}    
private void loadBeans(String location) throws Exception {     
	// 读取配置文件  
	InputStream is = new FileInputStream(location);  
	// 读入.xml文档需要一个DocumentBuilder对象  
	DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();  
	DocumentBuilder docBuilder = factory.newDocumentBuilder();  
	// 通过java IO 流的读取文件  
	Document document = docBuilder.parse(is);  
	Element root = document.getDocumentElement();  
	NodeList nodes = root.getChildNodes();  
	// 遍历bean标签  
	for (int i = 0; i < nodes.getLength(); i++) {
	   Node node = nodes.item(i);   
	   if (node instanceof Element) {
	       Element e = (Element) node;    
	       String id = e.getAttribute("id");    
	       String classname = e.getAttribute("class");    
	       // 加载beanClass    
	       Class beanClass = null;    
	       beanClass = Class.forName(classname);    
	       // 创建bean    
	       Object bean = beanClass.newInstance();    
	       // 遍历 <property> 标签    
	       NodeList propertiesList = e.getElementsByTagName("property");    
	       for (int j = 0; j < propertiesList.getLength(); j++) {
	            Node propertyNode = propertiesList.item(j);     
	            if (propertyNode instanceof Element) {
	                  Element proElement = (Element) propertyNode;      
	                  String name = proElement.getAttribute("name");      
	                  String value = proElement.getAttribute("value");      
	                  // 利用反射将bean相关字段f访问权限设为可访问      
	                  Field declaredField = bean.getClass().getDeclaredField(name);      
	                  declaredField.setAccessible(true);      
	                  if (value != null && value.length() > 0) {       
	                  // 把属性值填充到相关字段
	                         declaredField.set(bean, value);      
	                  } else {
	                         String ref = proElement.getAttribute("ref");       
	                         if (ref == null || ref.length() == 0) {
	                                 throw new IllegalArgumentException("ref config error");       
	                         }       
	                         declaredField.set(bean, getBean(ref));     
	                  }      
	                  // 把bean注册到容器当中      
	         		beanmap.put(id, bean);     
	     		}
			}   
		}  
	} 
}

获取bean的方法:

public Object getBean(String name) {
  // TODO Auto-generated method stub
  Object bean = beanmap.get(name);
  if (bean == null) {
   throw new IllegalArgumentException("there is no bean with name " + name);
  }
  return bean;
 }

测试

接下来测试一下好不好使:

  1. 配置文件:
<bean id="computer" class="com.ioc.entry.Computer">
        <property name="name" value="拯救者 Y7000"/>
        <property name="weight" value="2.3kg"/>
        <property name="size" value="15.6英寸"/>
</bean>
  1. 实体类
public class Computer {
	private String name;
	private String weight;
	private String size;
	//...省略get/set方法
}
  1. 测试类
		String location = IOCDemo.class.getClassLoader().getResource("resource/test.xml").getFile();
		IOCDemo demo = new IOCDemo(location);
		Computer computer = (Computer) demo.getBean("computer");
		System.out.println(computer);
  1. 结果

Computer [name=拯救者 Y7000, weight=2.3kg, size=15.6英寸]

  1. 完整例子
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值