Spring的IOC让被调用者从调用者中实例化解脱出来。而是通过spring的容器去实现配置文件的解析,以及向容器的注入。
Spring的容器使用了工厂的模式,里面实际是用一个Map存放bean标签的id值和实例化的对象。
下面是一个简单的spring的IOC实例
首先定义model
package com.zhy.spring.framework.bean;
/**
* model
*
* @author Create date
*/
public class JavaBean {
private String name;
private String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
接下来定义配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="javaBean" class="com.zhy.spring.framework.bean.JavaBean">
<property name="name">
<value>James</value>
</property>
<property name="age">
<value>12</value>
</property>
</bean>
</beans>
最后定义spring工厂,他完成配置文件的解析,以及IOC的注入
package com.zhy.spring.framework.factory;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.zhy.spring.framework.bean.JavaBean;
public class SpringFactory {
/**
* key表示映射文件中bean节点的ID
* value 表示bean对应的对象
*/
private Map<String,Object> factory = new HashMap<String,Object>();
/**
* 解析xml配置文件,ioc对象,最后放入factory中
* @param xmlPath 配置文件的路径
*/
public void init(String xmlPath){
try{
//使用SaxReader进行xml配置文件的读取。
SAXReader saxReader = new SAXReader();
//saxReader的read方法才会返回xml对应的Document,所以需要创建reader对应的InputStream参数
//通过classLoader的getResourceAsStream可以获取对应的InputStream,所以要获取classLoader
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream in = classLoader.getResourceAsStream(xmlPath);
Document document = saxReader.read(in);
Element root = document.getRootElement();
//遍历root元素下的bean节点,使用element.elementIterator方法
for(Iterator it = root.elementIterator("bean");it.hasNext();){
Element beanEle = (Element)it.next();
//获取ID和class属性
Attribute idAttr = beanEle.attribute("id");
Attribute classAttr = beanEle.attribute("class");
/*
*利用java反射获取class对象
*attribute.getText()后去属性节点对应的值
*beanClass主要的作用就是获取该Class对应的对象的
*/
Class beanClass = Class.forName(classAttr.getText());
//获取beanInfo,beanInfo可以获取该类所具有的属性和方法的相关信息
BeanInfo beanInfo = Introspector.getBeanInfo(beanClass);
//获取属性描述
PropertyDescriptor[] pd = beanInfo.getPropertyDescriptors();
//获取实例话对象
Object obj = beanClass.newInstance();
//对bean下的property节点进行遍历
for(Iterator proIte = beanEle.elementIterator("property");proIte.hasNext();){
Element proEle = (Element)proIte.next();
Attribute nameAttri = proEle.attribute("name");
String value=null;
//对property下的value节点进行遍历
for(Iterator valueIte = proEle.elementIterator("value");valueIte.hasNext();){
Element valueEle = (Element)valueIte.next();
value = valueEle.getText();
break;
}
/*
* 将获取的值注入到bean中,利用反射
* 遍历pd数组,找到和name属性节点文本的值相同的项
* 然后将value值注入到对象当中,最后将id和对象存储于map中
*/
for(int i = 0 ; i < pd.length;i++){
PropertyDescriptor descriptor = pd[i];
if(descriptor.getName().equals(nameAttri.getText())){
Method writeMethod = descriptor.getWriteMethod();
writeMethod.invoke(obj,value);
}
}
//将对象放入map中
factory.put(idAttr.getText(),obj);
}
}
}catch(Exception e){
System.out.println(e.getMessage());
}
}
/**
* 根据xml的bean ID获取对应的class实例
* @param beanName
* @return 实例对象
*/
public Object getBean(String beanName){
return factory.get(beanName);
}
public static void main(String[] args) {
//URL url = SpringFactory.class.getResource("/");
String xmlPath = "config.xml";
//System.out.println(xmlPath);
SpringFactory factory = new SpringFactory();
factory.init(xmlPath);
JavaBean bean = (JavaBean)factory.getBean("javaBean");
//System.out.println(bean.getName());
//System.out.println(bean.getAge());
}
}
实现简单spring的IOC
猜你喜欢
转载自jameszhao1987.iteye.com/blog/1309704
今日推荐
周排行