TA的每日心情 | 开心 2020-11-11 23:19 |
---|
签到天数: 20 天 [LV.4]偶尔看看III 成长值: 23480
|
package com.zhangjie.ioc;
import java.beans.IntrospectionException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
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 void init(String xml){
try {
//读取配置文件
SAXReader reader = new SAXReader();
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
//从class目录下获取指定的xml文件
InputStream ins = classLoader.getResourceAsStream(xml);
Document doc = reader.read(ins);
Element root = doc.getRootElement();
System.out.println(root.getName());
Element foo;
Iterator i = root.elementIterator("bean");
while(i.hasNext()){
foo = (Element)i.next();
//获取bean的属性id和class
Attribute id = foo.attribute("id");
Attribute cls = foo.attribute("class");
//利用Java反射机制,通过class的名称获取Class对象
Class bean = Class.forName(cls.getText());
//获取对应class的信息
java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(bean);
//获取其属性描述
java.beans.PropertyDescriptor pd[] =
info.getPropertyDescriptors();
//设置值的方法
Method mSet = null;
//创建一个对象
Object obj = bean.newInstance();
//遍历该bean的property属性
Iterator ite = foo.elementIterator("property");
while(ite.hasNext()){
Element foo2 = (Element)ite.next();
//获取该property的name属性
Attribute name = foo2.attribute("name");
String value = null;
//获取该property的子元素value的值
Iterator ite1 = foo2.elementIterator("value");
while(ite1.hasNext()){
Element node = (Element)ite1.next();
value = node.getText();
break;
}
for(int k = 0;k < pd.length;k++){
if(pd[k].getName().equalsIgnoreCase(name.getText())){
mSet = pd[k].getWriteMethod();
//利用Java的反射机制调用对象的某个set方法,并将值设置进去
mSet.invoke(obj, value);
}
}
}
//将对象放入beanMap中,其中key为id值,value为对象
beanMap.put(id.getText(), obj);
}
} catch (DocumentException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IntrospectionException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
public Object getBean(String beanName){
Object obj = beanMap.get(beanName);
return obj;
}
public static void main(String[] args) {
BeanFactory factory = new BeanFactory();
factory.init("config.xml");
JavaBean javaBean = (JavaBean)factory.getBean("javaBean");
System.out.println("userName="+javaBean.getUserName());
System.out.println("password="+javaBean.getPassword());
}
}
该类的init(xml)方法,通过指定的xml来给对象注入属性,为了对该类进行测试,我还需要新建一个JavaBean和在src目录下新建一个名为config.xml的配置文件。JavaBean的内容如下:
package org.amigo.reflection;
public class JavaBean {
private String userName;
private String password;
public String getPassword() {
return password;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public void setPassword(String password) {
this.password = password;
}
}
这个简单bean对象中有两个属性,分别为userName和password,下面我们在配置文件config.xml中对其属性注入对应的属性值。配置文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="javaBean" class="org.amigo.reflection.JavaBean">
<property name="userName">
<value>阿蜜果</value>
</property>
<property name="password">
<value>12345678</value>
</property>
</bean>
</beans>
类与配置文件都完成后,可以运行BeanFactory.java文件,控制台显示内容为:
userName=阿蜜果
password=12345678
可以看到,虽然在main()方法中没有对属性赋值,但属性值已经被注入,在BeanFactory类中的Class bean = Class.forName(cls.getText());通过类名来获取对应的类,mSet.invoke(obj, value);通过invoke方法来调用特定对象的特定方法,实现的原理都是基于Java的反射机制,在此我们有一次见证了Java反射机制的强大。 |
|