IOC(Inversion of Control),即控制反转,它使你不需要再自己来实现对象的创建,而是把这些工作都交由容器来进行管理,增加了代码的可重用性。该段代码通过读取config.xml(代码片段3),获得需要创建对象的类的全名,通过反射机制实例化对象,并将xml文件里面的参数通过set方法传递到 返回的对象里面,简单实现了 ioc 的原理。
代码片段1:BeanFactory
package com.ghrt.frame.spring;
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.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class BeanFactory {
private Map<String, Object> beanMap = new HashMap<String, Object>();
public BeanFactory()
{
//读取指定的配置文件
SAXReader reader = new SAXReader();
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
//从class目录下获取指定的xml文件
InputStream ins = classLoader.getResourceAsStream("config.xml");
Document doc;
try {
doc = reader.read(ins);
Element root = doc.getRootElement();
Iterator element = root.elementIterator("bean");
while(element.hasNext())
{
Element foo = (Element)element.next();
//获得 bean 类的名称 和 id
Attribute cls = foo.attribute("class");
Attribute id = foo.attribute("id");
//通过类名反射得到类
Class clazz = Class.forName(cls.getText());
//获取对应class的信息
java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(clazz);
//获取其属性描述
java.beans.PropertyDescriptor pd[] = info.getPropertyDescriptors();
//设置值的方法
Method mSet = null;
//创建一个对象
Object obj = clazz.newInstance();
//遍历该 bean 的 property 属性
Iterator element1 = foo.elementIterator("property");
while(element1.hasNext())
{
Element foo1 = (Element)element1.next();
//读取该 bean 的 value 值
Iterator element2 = foo1.elementIterator("value");
Element foo2 = (Element)element2.next();
String value = foo2.getText();
//遍历 bean 的方法,根据判断 执行相应的 set 方法
for(int i=0;i<pd.length;i++){
if(foo1.attributeValue("name").equalsIgnoreCase(pd[i].getName())){
//System.out.println(pd[i].getName());
System.out.println(pd[i].getWriteMethod());
mSet = pd[i].getWriteMethod();
//执行方法
mSet.invoke(obj, value);
}
}
}
beanMap.put(id.getText(), obj);
}
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}
}
/**
* 通过bean的id获取bean的对象.
* @param beanName bean的id
* @return 返回对应对象
**/
public Object getBean(String beanName) {
Object obj = beanMap.get(beanName);
return obj;
}
public static void main(String[] args)
{
BeanFactory beanFactory = new BeanFactory();
//JavaBean 见代码片段2
JavaBean javaBean = (JavaBean)beanFactory.getBean("javaBean");
System.out.println("test userName:"+javaBean.getUserName());
System.out.println("test passwd:"+javaBean.getPassword());
}
}
main 方法执行结果:
代码片段2(JavaBean):
package com.ghrt.frame.spring;
public class JavaBean {
private String userName;
private String password;
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
System.out.println("Execute set method");
this.userName = userName;
}
}
代码片段3(config.xml,类似 spring 中的配置文件):
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="javaBean" class="com.ghrt.frame.spring.JavaBean">
<property name="userName">
<value>阿蜜果</value>
</property>
<property name="password">
<value>12345678</value>
</property>
</bean>
</beans>