奔主题:模拟SpringBean工厂:
先来一个简单的interface:beanFactory
package cn.asto.spring; public interface BeanFactory { public Object getBean(); }
一个最简单的Spring配置文件:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="v" class="cn.asto.spring.Car"> </bean> </beans>
现在我们已经有了配置文件,有了BeanFactroy接口,接下来要做的就是实现一个BeanFactory的接口。
这个实现中做那么几件事情:
- 读入配置文件
- 利用反射将类名字符串实例化成对象
- 将对象注入Map(这个Map就是Spring的Bean容器)
- 通过<key,value>的形式获取对象
- 读入配置文件
我这里使用JDOM(利用了XPath语法):
package cn.asto.spring; import java.util.HashMap; import java.util.List; import java.util.Map; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.filter.Filters; import org.jdom2.input.SAXBuilder; import org.jdom2.xpath.XPathExpression; import org.jdom2.xpath.XPathFactory; public class ClassPathXmlApplicationContext implements BeanFactory{ public ClassPathXmlApplicationContext(String xml) throws Exception{ //读入XML文件 SAXBuilder sax = new SAXBuilder(); Document doc = sax.build(ClassPathXmlApplicationContext.class.getClassLoader().getResource(xml)); XPathFactory xFactory = XPathFactory.instance(); XPathExpression<Element> expr = xFactory.compile("/beans/bean", Filters.element()); List<Element> beans = expr.evaluate(doc); for (Element bean : beans) { String id = bean.getAttributeValue("id"); String value = bean.getAttributeValue("class"); } } @Override public Object getBean(String key) { return null; } }
- 利用反射将类名 字符串实例化成对象
- 将对象注入Map(这个Map就是Spring的Bean容器)
- 通过<key,value>的形式获取对象
package cn.asto.spring; import java.util.HashMap; import java.util.List; import java.util.Map; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.filter.Filters; import org.jdom2.input.SAXBuilder; import org.jdom2.xpath.XPathExpression; import org.jdom2.xpath.XPathFactory; public class ClassPathXmlApplicationContext implements BeanFactory{ private Map<String,Object> map = new HashMap<String,Object>(); public ClassPathXmlApplicationContext(String xml) throws Exception{ //读入XML文件 SAXBuilder sax = new SAXBuilder(); Document doc = sax.build(ClassPathXmlApplicationContext.class.getClassLoader().getResource(xml)); XPathFactory xFactory = XPathFactory.instance(); XPathExpression<Element> expr = xFactory.compile("/beans/bean", Filters.element()); List<Element> beans = expr.evaluate(doc); for (Element bean : beans) { String id = bean.getAttributeValue("id"); String value = bean.getAttributeValue("class"); System.out.println(value); //反射实例化对象 Object o = Class.forName(value).newInstance(); //经典IOC注入容器 map.put(id, o); } } @Override public Object getBean(String key) { //得到Bean return map.get(key); } }
测试一下:
package cn.asto.spring; public class Test { public static void main(String args[]) throws Exception { BeanFactory factory = new ClassPathXmlApplicationContext("cn/asto/spring/applicationContext.xml"); Car car = (Car)factory.getBean("v"); car.move(); } }
输出:
car is running.
ok,spring的IOC模拟完成!
哦。忘记把Car类放上来了:
package cn.asto.spring; public class Car { public void move(){ System.out.println("car is running"); } }