自己实现的Spring IOC容器

         该容器需要借助于Dom4jJar包来解析XML文件。

1.

package com.lanp.myioc;

/**
 * 输出接口
 * @author LanP
 */
public interface Output {
 /**
  * 获取输出消息
  * @param msg
  * @return String
  */
 String getMsg(String msg);
 
 void out();
}

2.

package com.lanp.myioc;

/**
 * 带缓存的打印机
 * @author LanP
 */
public class BuffPrinter implements Output {
 
 private static final int MAX_SIZE = 1024;
 private StringBuffer[] printMsg = new StringBuffer[MAX_SIZE * 2];
 /**
  * 记录当前打印的作用位置
  */
 private int msgNum = 0;
 
 
 @Override
 public String getMsg(String msg) {
  if(msgNum >= MAX_SIZE){
   System.out.println("输出管道队列已满,添加失败!");
  } else {
   printMsg[msgNum++] = new StringBuffer(msg);
  }
   
  return msg;
 }

 @Override
 public void out() {
  //只要尚有作用没有打印就继续打印
  while(msgNum > 0) {
   System.out.println("缓存打印机打印: " + printMsg[0].toString());
   //将作业队列向前移一位,剩下的作业书量减一
   System.arraycopy(printMsg, 1, printMsg, 0, --msgNum);
  }
 }
 
}

3.

package com.lanp.myioc;

/**
 * 普通打印机类,实现了输出接口
 * @author LanP
 */
public class Printer implements Output {
 
 private static final int MAX_SIZE = 1024;
 private String[] printMsg = new String[MAX_SIZE];
 /**
  * 记录当前打印的作用位置
  */
 private int msgNum = 0;
 
 
 @Override
 public String getMsg(String msg) {
  if(msgNum >= MAX_SIZE){
   System.out.println("输出管道队列已满,添加失败!");
  } else {
   printMsg[msgNum++] = msg;
  }
   
  return msg;
 }

 @Override
 public void out() {
  //只要尚有作用没有打印就继续打印
  while(msgNum > 0) {
   System.out.println("普通打印机打印: " + printMsg[0]);
   //将作业队列向前移一位,剩下的作业书量减一
   System.arraycopy(printMsg, 1, printMsg, 0, --msgNum);
  }
 }
 
}

4.

package com.lanp.myioc;

/**
 * 计算机实例,具有打印机
 * @author LanP
 * @version V1.0
 */
public class Computer {
 private String name;
 public void setName(String name) {
  this.name = name;
 }

 private Output output;
 
 public void setOutput(Output output) {
  this.output = output;
 }

 public Computer() {
  
 }
 
 public Computer(Output output) {
  this.output = output;
 }
 
 /**
  * 模拟消息输入的方法
  * @param msg
  */
 public void msgIn(String msg) {
  this.output.getMsg(msg);
 }
 
 /**
  * 模拟打印
  */
 public void print() {
  output.out();
 }
}

5.

<?xml version="1.0" encoding="UTF-8"?>
<beans>
 <bean id="computer" class="com.lanp.myioc.Computer">
  <property name="name" value="飘飘电脑" />
  <property name="output" ref="buffPrinter" />
 </bean>
 
 <bean id="printer" class="com.lanp.myioc.Printer"/>
 <bean id="buffPrinter" class="com.lanp.myioc.BuffPrinter"/>
 <bean id="nowtime" class="java.util.Date" scope="prototype" />
</beans>

6.

package com.lanp.myioc;

/**
 * 应用程序容器接口
 * @author LanP
 */
public interface MyApplicationContext {
 /**
  * 获取指定Bean实例的方法
  * @param name
  * @return Object
  * @throws Exception
  */
 Object getBean(String name) throws Exception;
}

7.

package com.lanp.myioc;

import java.io.File;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
 * 应用程序上下文容器实现类
 * @author LanP
 * @version V1.0
 */
public class MyXmlApplicationContext implements MyApplicationContext {
 /**
  * 保存容器中所以单例模式的Bean实例
  */
 private Map<String,Object> objPool = Collections.synchronizedMap(new HashMap<String,Object>());
 /**
  * 保存配置文件对于的Document对象
  */
 private Document document;
 /**
  * 保存配置文件中的根元素
  */
 private Element root;
 
 public MyXmlApplicationContext(String filePath) throws Exception {
  SAXReader reader = new SAXReader();
  document = reader.read(new File(filePath));
  root = document.getRootElement();
  initPool();
  initProp();
 }
 
 /**
  * 初始化容器中的属性
  * @throws Exception
  */
 @SuppressWarnings("unchecked")
 private void initProp() throws Exception {
  //遍历配置文件里的每个<bean>标签
  for(Object obj:root.elements()) {
   Element beanElement = (Element)obj;
   //取得bean元素中的ID
   String beanId = beanElement.attributeValue("id");
   //取得bean元素中的scope
   String beanScope = beanElement.attributeValue("scope");
   //如果Bean标签中的scope不存在或为singleton
   if(null == beanScope || beanScope.equals("singleton")) {
    //取出objPool中的bean实例
    Object bean = objPool.get(beanId);
    //遍历Bean元素中的每个property
    for(Object prop: beanElement.elements()) {
     Element propElement = (Element)prop;
     //取得property元素的name
     String propName = propElement.attributeValue("name");
     //取得property元素的value
     String propValue = propElement.attributeValue("value");
     //取得property元素的ref
     String propRef = propElement.attributeValue("ref");
     //将属性名首字母大写
     String propNameUpCase = propName.substring(0,1).toUpperCase()
      + propName.substring(1, propName.length());
     //如果property元素的value存在
     if(null != propValue && propValue.length() > 0) {
      //获取设置注入的set方法
      Method setter = bean.getClass().getMethod("set" + propNameUpCase, String.class);
      //执行set注入
      setter.invoke(bean, propValue);
     }
     
     if(null != propRef && propRef.length() > 0) {
      //取出需要依赖注入的bean实例
      Object target = objPool.get(propRef);
      //objPool不存在指定的实例
      if(null == target) {
       System.out.println("不存在你要注入的bean实例");
      }
      //定义设值注入所需的set方法
      Method setter = null;
      //遍历target对象实现的所有接口
      for(Class superInterface : target.getClass().getInterfaces()) {
       try {
        //获取设值注入所需的setter方法
        setter = bean.getClass().getMethod("set" + propNameUpCase,superInterface);
        //如果成功获得该接口对应的方法,直接跳出循环
        break;
       } catch (Exception e) {
        //如果没有找到对应的setter方案,继续下次循环
        continue;
       }
      }
      //如果setter方法依然为null
      //则直接获得target实现类对应的setter方法
      if(null == setter) {
       setter = bean.getClass().getMethod("set" + propNameUpCase, target.getClass());
      }
      //执行setter注入
      setter.invoke(bean, target);
     }
    }
   }
  }
 }
 
 /**
  * 初始化容器中所有的单例bean
  * @throws Exception
  */
 private void initPool() throws Exception {
  //遍历配置文件里面的每个<bean>标签
  for(Object obj:root.elements()) {
   Element beanElement = (Element)obj;
   //取得Bean元素的Id
   String beanId = beanElement.attributeValue("id");
   //取得Bean元素的class
   String beanClass = beanElement.attributeValue("class");
   //取得bean元素的scope
   String beanScope = beanElement.attributeValue("scope");
   if(null == beanScope || beanScope.equals("singleton")) {
    //模拟构造器创建Bean实例,并将其实例放进objPool
    objPool.put(beanId, Class.forName(beanClass).newInstance());
   } else {
    //对于非单例的配置,将其bean类名放进objPool
    objPool.put(beanId, beanClass);
   }
  }
 }
 
 /**
  * 获取bean实例
  */
 @Override
 public Object getBean(String name) throws Exception {
  Object target = objPool.get(name);
  //对于单例bean,容器已经初始化了所有bean实例
  if(target.getClass() != String.class) {
   return target;
  } else {
   String clazz = (String)target;
   //对于prototype并未注入属性值
   return Class.forName(clazz).newInstance();
  }
 }

}

8.

package com.lanp.myioc;

public class MyIocTest {

 /**
  * 容器工厂的测试类
  * @param args
  */
 public static void main(String[] args) throws Exception {
  //创建IOC容器
  MyApplicationContext myApplicationContext = new MyXmlApplicationContext("D:\\lanp\\lanp\\eclipse\\my_workspace\\MyDesModPro\\src\\com\\lanp\\myioc\\bean.xml");
  //从IOC容器中取出Computer Bean
  Computer computer = (Computer)myApplicationContext.getBean("computer");
  //测试Computer对象
  computer.msgIn("飘");
  computer.msgIn("飘飘");
  computer.print();
  System.out.println(myApplicationContext.getBean("nowtime"));
 }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值