先定义一个BeanDefinition
public class BeanDefinition {
private String id;
private String className;
public BeanDefinition(String id, String className) {
this.id = id;
this.className = className;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
}
接着写IoC的实现容器,流程如下:
读取xml配置文件—>把配置文件内所有的bean节点信息添加到BeanDefinition容器内—>构造和BeanDefinition相应的BeanClass—>查找bean
public class MySpringApplicationContext {
/** *//** bean的信息集合 */
private List<BeanDefinition> beanDefinitions = new ArrayList<BeanDefinition>();
/** *//** bean的class集合 */
private Map<String, Class> beanClass = new HashMap<String, Class>();
/** *//**
* 容器初始化
*
* @param fileName 配置文件(path和name)
*/
public MySpringApplicationContext(String fileName) {
readXML(fileName);
initBeanClass(beanDefinitions);
}
/** *//**
* 获取MySpringApplicationContext容器内的bean实例
*
* @param id bean id
* @return bean实例
*/
public Object getBean(String id) {
try {
return beanClass.get(id).newInstance();
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
/** *//**
* 初始化所有bean的class
*
* @param beanDefinitions bean定义信息
*/
private void initBeanClass(List<BeanDefinition> beanDefinitions) {
for (BeanDefinition beanDefinition : beanDefinitions) {
if (beanDefinition.getClassName() != null && beanDefinition.getClassName().length() != 0) {
beanClass.put(beanDefinition.getId(), getClass(beanDefinition));
} else {
throw new RuntimeException("class is empty");
}
}
}
/** *//**
* 读取XML文件(利用dom4j,加dom4j-1.6.1.jar、jaxen-1.1-beta-7.jar文件)
*
* @param fileName 配置文件(path和name)
*/
private void readXML(String fileName) {
SAXReader reader = new SAXReader();
Document document = null;
URL url = getClass().getClassLoader().getResource(fileName);
try {
document = reader.read(url);
Map<String, String> nameSpaceMap = new HashMap<String, String>();
nameSpaceMap.put("namespace", "http://www.springframework.org/schema/beans"); // 加入命名空间
XPath xpath = document.createXPath("//namespace:beans/namespace:bean"); // 创建查询路径(beans根目录下的bean元素)
xpath.setNamespaceURIs(nameSpaceMap); // 设置命名空间
List<Element> beans = xpath.selectNodes(document); // 获取beans根目录下的所有bean节点
for (Element element : beans) {
String id = element.attributeValue("id"); // 获取id属性值
String className = element.attributeValue("class"); // 获取class属性值
BeanDefinition definition = new BeanDefinition(id, className);
beanDefinitions.add(definition);
}
} catch (DocumentException e) {
throw new RuntimeException("failed to read xml file!", e);
}
}
/** *//**
* 获取class
*
* @param beanDefinition bean定义信息
* @return class
*/
private Class getClass(BeanDefinition beanDefinition) {
try {
return Class.forName(beanDefinition.getClassName());
} catch (ClassNotFoundException e) {
throw new RuntimeException("class not found!", e);
}
}
}
XML文件:
<?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-2.0.xsd">
<bean id="productDao" class="ProductDao">
</bean>
</beans>
Bean:
public class ProductDao {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void save() {
System.out.println("产品插入数据库");
}
}
测试类:
public class SpringTest {
public static void main(String[] args) {
MySpringApplicationContext applicationContext = new MySpringApplicationContext("applicationContext.xml");
ProductDao productDao = (ProductDao)applicationContext.getBean("productDao");
productDao.save();
}
}
测试结果:产品插入数据库