配置檔案setting.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="me" class="com.zj.ioc.di.imp.Person">
<property name="name">
<value>ZJ</value>
</property>
<property name="age">
<value>26</value>
<property name="height">
<value>1.78</value>
</bean>
<bean id="you" class="com.zj.ioc.di.imp.Person">
<value>Mary</value>
<value>27</value>
<value>1.66</value>
<bean id="myList" class="com.zj.ioc.di.imp.ListOne">
<property name="msg">
<list>
<value>java</value>
<value>c</value>
<value>windows</value>
</list>
<bean id="mySet" class="com.zj.ioc.di.imp.SetOne">
<set>
<value>tom</value>
<value>cat</value>
<value>dog</value>
</set>
<bean id="myMap" class="com.zj.ioc.di.imp.MapOne">
<map>
<entry key="c">
<value>CHINA</value>
</entry>
<entry key="j">
<value>JAPAN</value>
<entry key="k">
<value>KOREA</value>
</map>
<bean id="us" class="com.zj.ioc.di.imp.Persons">
<property name="i">
<ref bean="me" />
<property name="u">
<ref bean="you" />
</beans>
依據setting.xml,這裡将建構兩個Person類的執行個體me和you:
Person.java
<b>package</b> com.zj.ioc.di.imp;
<b>public</b> <b>class</b> Person {
<b>private</b> String name;
<b>private</b> <b>int</b> age;
<b>private</b> <b>float</b> height;
<b>public</b> String getName() {<b>return</b> name;}
<b>public</b> <b>void</b> setName(String name) {<b>this</b>.name = name;}
<b>public</b> <b>int</b> getAge() {<b>return</b> age;}
<b>public</b> <b>void</b> setAge(<b>int</b> age) {<b>this</b>.age = age;}
<b>public</b> <b>float</b> getHeight() {<b>return</b> height;}
<b>public</b> <b>void</b> setHeight(<b>float</b> height) {<b>this</b>.height = height;}
}
緊接着,建構一個ListOne的執行個體myList:
ListOne.java
<b>import</b> java.util.List;
<b>public</b> <b>class</b> ListOne {
<b>private</b> List<String> msg;
<b>public</b> List<String> getMsg() {<b>return</b> msg;}
<b>public</b> <b>void</b> setMsg(List<String> msg) {<b>this</b>.msg = msg;}
緊接着,建構一個SetOne的執行個體mySet:
SetOne.java
<b>import</b> java.util.Set;
<b>public</b> <b>class</b> SetOne {
<b>private</b> Set<String> msg;
<b>public</b> Set<String> getMsg() {<b>return</b> msg;}
<b>public</b> <b>void</b> setMsg(Set<String> msg) {<b>this</b>.msg = msg;}
緊接着,建構一個MapOne的執行個體myMap:
MapOne.java
<b>import</b> java.util.Map;
<b>public</b> <b>class</b> MapOne {
<b>private</b> Map<String,String> msg;
<b>public</b> Map<String, String> getMsg() {<b>return</b> msg;}
<b>public</b> <b>void</b> setMsg(Map<String, String> msg) {<b>this</b>.msg = msg;}
最後建構一個Persons類的執行個體us,其中包含me和you兩個已經建構好的對象:
Persons.java
<b>public</b> <b>class</b> Persons {
<b>private</b> Person i;
<b>private</b> Person u;
<b>public</b> Person getI() {<b>return</b> i;}
<b>public</b> <b>void</b> setI(Person i) {<b>this</b>.i = i;}
<b>public</b> Person getU() {<b>return</b> u;}
<b>public</b> <b>void</b> setU(Person u) {<b>this</b>.u = u;}
主要的實作機制是(代碼BeanFactory.java以及工程見附件),
1.通過一個HashMap儲存構造好的對象,key就是bean的id屬性,value就是這個對象;
<b>private</b> Map<String, Object> beanMap = <b>new</b> HashMap<String, Object>();
……
<b>public</b> Object getBean(String beanId) {
Object obj = beanMap.get(beanId);
<b>return</b> obj;
查詢時
BeanFactory factory = <b>new</b> BeanFactory();
factory.init("setting.xml");
Person p1 = (Person) factory.getBean("me");
2.init方法讀入配置檔案setting.xml,并直接定位到beans下的bean元素,并執行個體化一個ElementHandler對其處理。
<b>public</b> <b>void</b> init(String xmlUri) <b>throws</b> Exception {
SAXReader saxReader = <b>new</b> SAXReader();
File file = <b>new</b> File(xmlUri);
<b>try</b> {
saxReader.addHandler("/beans/bean", <b>new</b> BeanHandler());
saxReader.read(file);
} <b>catch</b> (DocumentException e) {
System.out.println(e.getMessage());
}
3.ElementHandler,dom4j的ElementHandler接口有兩個方法,一個是onStart(),它主要用于處理該元素的屬性以及動态增加新的Handler類;另一個是onEnd(),它主要用于獲得該元素的Text文本以及删除已添加的Handler。
BeanHandler
<b>private</b> <b>class</b> BeanHandler <b>implements</b> ElementHandler {
Object obj = <b>null</b>;
<b>public</b> <b>void</b> .Start(ElementPath path) {
Element beanElement = path.getCurrent();
Attribute classAttribute = beanElement.attribute("class");
Class<?> bean = <b>null</b>;
<b>try</b> {
bean = Class.forName(classAttribute.getText());
} <b>catch</b> (ClassNotFoundException e) {
e.printStackTrace();
}
Field fields[] = bean.getDeclaredFields();
Map<String, Field> mapField = <b>new</b> HashMap<String, Field>();
<b>for</b> (Field field : fields)
mapField.put(field.getName(), field);
obj = bean.newInstance();
} <b>catch</b> (InstantiationException e) {
} <b>catch</b> (IllegalAccessException e) {
path.addHandler("property", <b>new</b> PropertyHandler(mapField, obj));
<b>public</b> <b>void</b> .End(ElementPath path) {
Attribute idAttribute = beanElement.attribute("id");
beanMap.put(idAttribute.getText(), obj);
path.removeHandler("property");
PropertyHandler
<b>private</b> <b>class</b> PropertyHandler <b>implements</b> ElementHandler {
Map<String, Field> mapField;
Object obj;
<b>public</b> PropertyHandler(Map<String, Field> mapField, Object obj) {
<b>this</b>.mapField = mapField;
<b>this</b>.obj = obj;
Element propertyElement = path.getCurrent();
Attribute nameAttribute = propertyElement.attribute("name");
path.addHandler("value", <b>new</b> ValueHandler(mapField, obj,
nameAttribute));
path.addHandler("list", <b>new</b> ListHandler(mapField, obj,
path.addHandler("set", <b>new</b> SetHandler(mapField, obj,
path.addHandler("map", <b>new</b> MapHandler(mapField, obj,
path.addHandler("ref", <b>new</b> RefHandler(mapField, obj,
path.removeHandler("value");
path.removeHandler("list");
path.removeHandler("set");
path.removeHandler("map");
path.removeHandler("ref");
根據setting.xml,我們可以得到各種注入元素的Handler類處理流程圖。
4. setFieldValue()基于反射機制和相應的類資訊得到Field的類型,并根據setting.xml設定它的值。
<b>private</b> <b>void</b> setFieldValue(Object obj, Field field, String value) {
String fieldType = field.getType().getSimpleName();
<b>if</b> (fieldType.equals("int"))
field.setInt(obj, <b>new</b> Integer(value));
<b>else</b> <b>if</b> (fieldType.equals("float"))
field.setFloat(obj, <b>new</b> Float(value));
<b>else</b> <b>if</b> (fieldType.equals("boolean"))
field.setBoolean(obj, <b>new</b> Boolean(value));
<b>else</b> <b>if</b> (fieldType.equals("char"))
field.setChar(obj, value.charAt(0));
<b>else</b> <b>if</b> (fieldType.equals("double"))
field.setDouble(obj, <b>new</b> Double(value));
<b>else</b> <b>if</b> (fieldType.equals("long"))
field.setLong(obj, <b>new</b> Long(value));
<b>else</b>
field.set(obj, value);
} <b>catch</b> (IllegalArgumentException e) {
e.printStackTrace();
} <b>catch</b> (IllegalAccessException e) {
<b>private</b> <b>void</b> setFieldValue(Object obj, Field field, List<String> value) {
field.set(obj, value);
5.測試
<b>public</b> <b>static</b> <b>void</b> main(String[] args) {
BeanFactory factory = <b>new</b> BeanFactory();
factory.init("setting.xml");
Person p1 = (Person) factory.getBean("me");
System.out.print(p1.getName() + " ");
System.out.print(p1.getAge() + " ");
System.out.println(p1.getHeight());
Person p2 = (Person) factory.getBean("you");
System.out.print(p2.getName() + " ");
System.out.print(p2.getAge() + " ");
System.out.println(p2.getHeight());
ListOne list = (ListOne) factory.getBean("myList");
System.out.println(list.getMsg());
SetOne set = (SetOne) factory.getBean("mySet");
System.out.println(set.getMsg());
MapOne map = (MapOne) factory.getBean("myMap");
System.out.println(map.getMsg());
Persons us = (Persons) factory.getBean("us");
System.out.println(us.getI());
System.out.println(us.getU());
} <b>catch</b> (Exception e) {
測試結果:
ZJ 26 1.78
Mary 27 1.66
[java, c, windows]
[cat, tom, dog]
{c=CHINA, j=JAPAN, k=KOREA}
com.zj.ioc.di.imp.Person@1a5ab41
com.zj.ioc.di.imp.Person@18e3e60
本文轉自zhangjunhd51CTO部落格,原文連結:http://blog.51cto.com/zhangjunhd/126545,如需轉載請自行聯系原作者