spring依赖注入原理(转载)
關于spring依賴注入原理的文章在網絡上已經有很多,我要寫的這篇文章原文出自http://taeky.iteye.com/blog/563450,只所以再一次寫下來只是為了一為自己收藏,方便以后的復習;二是自己在用這個例子實踐的時候遇到一些問題,自己記一下。另外這篇文章中用dom4j來解析spring的配置文件,我覺得也是個值得學習的地方。好了,不多說了,還是把代碼再貼一下:?
接口:PersonDao.java
Java代碼??
package?com.luojing.test.dao;??
??
public?interface?PersonDao?{??
??????
????public?void?add();??
??
}??
實現類:PersonDaoImp.java
Java代碼??
package?com.luojing.test.daoimp;??
??
import?com.luojing.test.dao.PersonDao;??
??
public?class?PersonDaoImp?implements?PersonDao?{??
??
????public?void?add()?{??
??????????
????????System.out.println("執行了add()方法!!!");??
????}??
??
}??
服務接口:PersonService.java
Java代碼??
package?com.luojing.test.service;??
??
public?interface?PersonService?{??
??????
????public?void?save();??
??
}??
服務實現類:PersonServiceImp.java
Java代碼??
package?com.luojing.test.serviceimp;??
??
import?com.luojing.test.dao.PersonDao;??
import?com.luojing.test.service.PersonService;??
??
public?class?PersonServiceImp?implements?PersonService?{??
??????
????private?PersonDao?personDao;??
??????
????public?PersonDao?getPersonDao()?{??
????????return?personDao;??
????}??
??
????public?void?setPersonDao(PersonDao?personDao)?{??
????????this.personDao?=?personDao;??
????}??
??
????public?void?save()?{??
??????????
????????personDao.add();??
??????
????}??
??
}??
applicationContext.xml配置文件如下:
Java代碼??
<?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.5.xsd"?>??
?????????????
<bean?id="personDao"?class="com.luojing.test.daoimp.PersonDaoImp"/>??
??
<bean?id="service"?class="com.luojing.test.serviceimp.PersonServiceImp">??
??
<property?name="personDao"?ref="personDao"></property>??
??
</bean>??
??
</beans>??
創建bean,然后其屬性用一集合存儲在bean里BeanDefinition.java:
Java代碼??
package?com.luojing.test.testioc;??
??
import?java.util.ArrayList;??
import?java.util.List;??
??
public?class?BeanDefinition?{??
??????
????private?String?id;??
??????
????private?String?classname;??
??????
????private?List<PropertyDefinition>?propertys?=?new?ArrayList<PropertyDefinition>();??
??
????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;??
????}??
??
????public?List<PropertyDefinition>?getPropertys()?{??
????????return?propertys;??
????}??
??
????public?void?setPropertys(List<PropertyDefinition>?propertys)?{??
????????this.propertys?=?propertys;??
????}??
??????
????public?BeanDefinition(String?id,String?classname){??
??????????
????????this.id?=?id;??
??????????
????????this.classname?=?classname;??
????}??
}??
屬性bean PropertyDefinition.java:
Java代碼??
package?com.luojing.test.testioc;??
??
public?class?PropertyDefinition?{??
??????
????private?String?name;??
??????
????private?String?ref;??
??
????public?String?getName()?{??
????????return?name;??
????}??
??
????public?void?setName(String?name)?{??
????????this.name?=?name;??
????}??
??
????public?String?getRef()?{??
????????return?ref;??
????}??
??
????public?void?setRef(String?ref)?{??
????????this.ref?=?ref;??
????}??
??????
????public?PropertyDefinition(String?name,String?ref){??
??????????
????????this.name?=?name;??
??????????
????????this.ref?=?ref;??
????}??
??
}??
解析spring配置文件并實例話bean ItcastClassPathXMLApplicationContext.java:
Java代碼??
package?com.luojing.test.testioc;??
??
import?java.beans.Introspector;??
import?java.beans.PropertyDescriptor;??
import?java.lang.reflect.Method;??
import?java.net.URL;??
import?java.util.ArrayList;??
import?java.util.HashMap;??
import?java.util.List;??
import?java.util.Map;??
??
import?org.dom4j.Document;??
import?org.dom4j.Element;??
import?org.dom4j.XPath;??
import?org.dom4j.io.SAXReader;??
??
public?class?ItcastClassPathXMLApplicationContext?{??
??????
?????private?List<BeanDefinition>?beanDefines?=?new?ArrayList<BeanDefinition>();????
???????
?????private?Map<String,?Object>?sigletons?=?new?HashMap<String,?Object>();????
??????
?????public?ItcastClassPathXMLApplicationContext(String?filename){??
??????????
????????this.readXML(filename);??
????????this.instanceBeans();??
????????this.injectObject();??
????}??
??????
?????/**???
?????*?實現bean的實例化???
?????*/????
????private?void?instanceBeans()?{?????
????????for?(BeanDefinition?beanDefinition?:?beanDefines)?{?????
????????????try?{?????
????????????????if?(beanDefinition.getClassname()?!=?null?&&?!"".equals(beanDefinition.getClassname().trim()))?????
????????????????????sigletons.put(beanDefinition.getId(),?Class.forName(?????
????????????????????????????beanDefinition.getClassname()).newInstance());?????
????????????}?catch?(Exception?e)?{?????
????????????????//?通過反射技術把bean都創建出來?????
????????????????e.printStackTrace();?????
????????????}?????
????????}?????
????
????}???
????/**???
?????*?為bean對象的屬性注入值???
?????*/????
????private?void?injectObject()?{?????
????????for?(BeanDefinition?beanDefinition?:?beanDefines)?{?????
????????????Object?bean?=?sigletons.get(beanDefinition.getId());?????
????????????if?(bean?!=?null)?{?????
????????????????try?{?????
????????????????????PropertyDescriptor[]?ps?=?Introspector.getBeanInfo(?????
????????????????????????????bean.getClass()).getPropertyDescriptors();?????
????????????????????//Introspector通過這個類可以取得bean的定義信息?????
????????????????????for?(PropertyDefinition?propertyDefinition?:?beanDefinition?????
????????????????????????????.getPropertys())?{?????
????????????????????????for?(PropertyDescriptor?properdesc?:?ps)?{????
?????????????
????????????????????????????if?(propertyDefinition.getName().equals(properdesc.getName()))?{?????
????????????????????????????????Method?setter?=?properdesc.getWriteMethod();//?獲取屬性的setter方法?????
????????????????????????????????????????????????????????????????????????????//?,private?????
????????????????????????????????if?(setter?!=?null)?{//屬性可能沒有set方法,所以這里要判斷一下?????
????????????????????????????????????Object?value?=?sigletons?????
????????????????????????????????????????????.get(propertyDefinition.getRef());?????
????????????????????????????????????setter.setAccessible(true);//如果set方法是私有的話,要設置它允許被訪問?????
????????????????????????????????????setter.invoke(bean,?value);//?把引用對象注入到屬性?????
????????????????????????????????}?????
????????????????????????????????break;?????
????????????????????????????}?????
????????????????????????}?????
????????????????????}?????
????????????????}?catch?(Exception?e)?{?????
????????????????}?????
????????????}?????
????????}?????
????}?????
??
????/**???
?????*?讀取xml配置文件???
?????*/????
????private?void?readXML(String?filename)?{?????
????????SAXReader?saxReader?=?new?SAXReader();?????
????????Document?document?=?null;?????
????????try?{?????
????????????URL?xmlpath?=?this.getClass().getClassLoader()?????
????????????????????.getResource(filename);?????
????????????document?=?saxReader.read(xmlpath);?????
????????????Map<String,?String>?nsMap?=?new?HashMap<String,?String>();?????
????????????nsMap.put("ns",?"http://www.springframework.org/schema/beans");//?加入命名空間?????
????????????XPath?xsub?=?document.createXPath("//ns:beans/ns:bean");//?創建beans/bean查詢路徑?????
????????????xsub.setNamespaceURIs(nsMap);//?設置命名空間?????
????????????List<Element>?beans?=?xsub.selectNodes(document);//?獲取文檔下所有bean節點?????
????????????for?(Element?element?:?beans)?{?????
????????????????String?id?=?element.attributeValue("id");//?獲取id屬性值?????
????????????????String?clazz?=?element.attributeValue("class");?//?獲取class屬性值?????
????????????????System.out.println(id?+?"?=?"?+?clazz);??
????????????????BeanDefinition?beanDefine?=?new?BeanDefinition(id,?clazz);?????
????????????????XPath?propertysub?=?element.createXPath("ns:property");?????
????????????????propertysub.setNamespaceURIs(nsMap);//?設置命名空間?????
????????????????List<Element>?propertys?=?propertysub.selectNodes(element);?????
????????????????for?(Element?property?:?propertys)?{?????
????????????????????String?propertyName?=?property.attributeValue("name");?????
????????????????????String?propertyref?=?property.attributeValue("ref");?????
????????????????????System.out.println(propertyName?+?"?=?"?+?propertyref);?????
????????????????????PropertyDefinition?propertyDefinition?=?new?PropertyDefinition(?????
????????????????????????????propertyName,?propertyref);?????
????????????????????beanDefine.getPropertys().add(propertyDefinition);?????
????????????????}?????
????????????????beanDefines.add(beanDefine);?????
????????????}?????
????????}?catch?(Exception?e)?{?????
????????????e.printStackTrace();?????
????????}?????
????}?????
??????
????/**???
?????*?獲取bean實例???
?????*/????
????public?Object?getBean(String?beanName)?{?????
????????return?this.sigletons.get(beanName);?????
????}???
??
}??
測試類SpringTest.java:
Java代碼??
package?com.luojing.test.testioc;??
??
import?com.luojing.test.service.PersonService;??
??
public?class?SpringTest?{??
??
??????
????public?static?void?main(String[]?args)?{??
??????????
?????????ItcastClassPathXMLApplicationContext?ctx?=?new?ItcastClassPathXMLApplicationContext("applicationContext.xml");???
???????????
?????????PersonService?ps?=?(PersonService)ctx.getBean("service");??
??????????????
?????????ps.save();??
????}??
??
} ?
總結
以上是生活随笔為你收集整理的spring依赖注入原理(转载)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在Java中设计和使用自己的注解(转载)
- 下一篇: java.sql.sqlexceptio