spring依赖注入原理(转载)

关于spring依赖注入原理的文章在网络上已经有很多,我要写的这篇文章原文出自http://taeky.iteye.com/blog/563450,只所以再一次写下来只是为了一为自己收藏,方便以后的复习;二是自己在用这个例子实践的时候遇到一些问题,自己记一下。另外这篇文章中用dom4j来解析spring的配置文件,我觉得也是个值得学习的地方。好了,不多说了,还是把代码再贴一下: 
接口:PersonDao.java

Java代码  

  1. package com.luojing.test.dao;  

  2.   

  3. public interface PersonDao {  

  4.       

  5.     public void add();  

  6.   

  7. }  


实现类:PersonDaoImp.java

Java代码  

  1. package com.luojing.test.daoimp;  

  2.   

  3. import com.luojing.test.dao.PersonDao;  

  4.   

  5. public class PersonDaoImp implements PersonDao {  

  6.   

  7.     public void add() {  

  8.           

  9.         System.out.println("执行了add()方法!!!");  

  10.     }  

  11.   

  12. }  


服务接口:PersonService.java

Java代码  

  1. package com.luojing.test.service;  

  2.   

  3. public interface PersonService {  

  4.       

  5.     public void save();  

  6.   

  7. }  


服务实现类:PersonServiceImp.java

Java代码  

  1. package com.luojing.test.serviceimp;  

  2.   

  3. import com.luojing.test.dao.PersonDao;  

  4. import com.luojing.test.service.PersonService;  

  5.   

  6. public class PersonServiceImp implements PersonService {  

  7.       

  8.     private PersonDao personDao;  

  9.       

  10.     public PersonDao getPersonDao() {  

  11.         return personDao;  

  12.     }  

  13.   

  14.     public void setPersonDao(PersonDao personDao) {  

  15.         this.personDao = personDao;  

  16.     }  

  17.   

  18.     public void save() {  

  19.           

  20.         personDao.add();  

  21.       

  22.     }  

  23.   

  24. }  


applicationContext.xml配置文件如下:

Java代码  

  1. <?xml version="1.0" encoding="UTF-8"?>  

  2. <beans xmlns="http://www.springframework.org/schema/beans"  

  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  

  4.        xsi:schemaLocation="http://www.springframework.org/schema/beans     

  5.            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd" >  

  6.              

  7. <bean id="personDao" class="com.luojing.test.daoimp.PersonDaoImp"/>  

  8.   

  9. <bean id="service" class="com.luojing.test.serviceimp.PersonServiceImp">  

  10.   

  11. <property name="personDao" ref="personDao"></property>  

  12.   

  13. </bean>  

  14.   

  15. </beans>  


创建bean,然后其属性用一集合存储在bean里BeanDefinition.java:

Java代码  

  1. package com.luojing.test.testioc;  

  2.   

  3. import java.util.ArrayList;  

  4. import java.util.List;  

  5.   

  6. public class BeanDefinition {  

  7.       

  8.     private String id;  

  9.       

  10.     private String classname;  

  11.       

  12.     private List<PropertyDefinition> propertys = new ArrayList<PropertyDefinition>();  

  13.   

  14.     public String getId() {  

  15.         return id;  

  16.     }  

  17.   

  18.     public void setId(String id) {  

  19.         this.id = id;  

  20.     }  

  21.   

  22.     public String getClassname() {  

  23.         return classname;  

  24.     }  

  25.   

  26.     public void setClassname(String classname) {  

  27.         this.classname = classname;  

  28.     }  

  29.   

  30.     public List<PropertyDefinition> getPropertys() {  

  31.         return propertys;  

  32.     }  

  33.   

  34.     public void setPropertys(List<PropertyDefinition> propertys) {  

  35.         this.propertys = propertys;  

  36.     }  

  37.       

  38.     public BeanDefinition(String id,String classname){  

  39.           

  40.         this.id = id;  

  41.           

  42.         this.classname = classname;  

  43.     }  

  44. }  


属性bean PropertyDefinition.java:

Java代码  

  1. package com.luojing.test.testioc;  

  2.   

  3. public class PropertyDefinition {  

  4.       

  5.     private String name;  

  6.       

  7.     private String ref;  

  8.   

  9.     public String getName() {  

  10.         return name;  

  11.     }  

  12.   

  13.     public void setName(String name) {  

  14.         this.name = name;  

  15.     }  

  16.   

  17.     public String getRef() {  

  18.         return ref;  

  19.     }  

  20.   

  21.     public void setRef(String ref) {  

  22.         this.ref = ref;  

  23.     }  

  24.       

  25.     public PropertyDefinition(String name,String ref){  

  26.           

  27.         this.name = name;  

  28.           

  29.         this.ref = ref;  

  30.     }  

  31.   

  32. }  


解析spring配置文件并实例话bean ItcastClassPathXMLApplicationContext.java:

Java代码  

  1. package com.luojing.test.testioc;  

  2.   

  3. import java.beans.Introspector;  

  4. import java.beans.PropertyDescriptor;  

  5. import java.lang.reflect.Method;  

  6. import java.net.URL;  

  7. import java.util.ArrayList;  

  8. import java.util.HashMap;  

  9. import java.util.List;  

  10. import java.util.Map;  

  11.   

  12. import org.dom4j.Document;  

  13. import org.dom4j.Element;  

  14. import org.dom4j.XPath;  

  15. import org.dom4j.io.SAXReader;  

  16.   

  17. public class ItcastClassPathXMLApplicationContext {  

  18.       

  19.      private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>();    

  20.        

  21.      private Map<String, Object> sigletons = new HashMap<String, Object>();    

  22.       

  23.      public ItcastClassPathXMLApplicationContext(String filename){  

  24.           

  25.         this.readXML(filename);  

  26.         this.instanceBeans();  

  27.         this.injectObject();  

  28.     }  

  29.       

  30.      /**   

  31.      * 实现bean的实例化   

  32.      */    

  33.     private void instanceBeans() {     

  34.         for (BeanDefinition beanDefinition : beanDefines) {     

  35.             try {     

  36.                 if (beanDefinition.getClassname() != null && !"".equals(beanDefinition.getClassname().trim()))     

  37.                     sigletons.put(beanDefinition.getId(), Class.forName(     

  38.                             beanDefinition.getClassname()).newInstance());     

  39.             } catch (Exception e) {     

  40.                 // 通过反射技术把bean都创建出来     

  41.                 e.printStackTrace();     

  42.             }     

  43.         }     

  44.     

  45.     }   

  46.     /**   

  47.      * 为bean对象的属性注入值   

  48.      */    

  49.     private void injectObject() {     

  50.         for (BeanDefinition beanDefinition : beanDefines) {     

  51.             Object bean = sigletons.get(beanDefinition.getId());     

  52.             if (bean != null) {     

  53.                 try {     

  54.                     PropertyDescriptor[] ps = Introspector.getBeanInfo(     

  55.                             bean.getClass()).getPropertyDescriptors();     

  56.                     //Introspector通过这个类可以取得bean的定义信息     

  57.                     for (PropertyDefinition propertyDefinition : beanDefinition     

  58.                             .getPropertys()) {     

  59.                         for (PropertyDescriptor properdesc : ps) {    

  60.              

  61.                             if (propertyDefinition.getName().equals(properdesc.getName())) {     

  62.                                 Method setter = properdesc.getWriteMethod();// 获取属性的setter方法     

  63.                                                                             // ,private     

  64.                                 if (setter != null) {//属性可能没有set方法,所以这里要判断一下     

  65.                                     Object value = sigletons     

  66.                                             .get(propertyDefinition.getRef());     

  67.                                     setter.setAccessible(true);//如果set方法是私有的话,要设置它允许被访问     

  68.                                     setter.invoke(bean, value);// 把引用对象注入到属性     

  69.                                 }     

  70.                                 break;     

  71.                             }     

  72.                         }     

  73.                     }     

  74.                 } catch (Exception e) {     

  75.                 }     

  76.             }     

  77.         }     

  78.     }     

  79.   

  80.     /**   

  81.      * 读取xml配置文件   

  82.      */    

  83.     private void readXML(String filename) {     

  84.         SAXReader saxReader = new SAXReader();     

  85.         Document document = null;     

  86.         try {     

  87.             URL xmlpath = this.getClass().getClassLoader()     

  88.                     .getResource(filename);     

  89.             document = saxReader.read(xmlpath);     

  90.             Map<String, String> nsMap = new HashMap<String, String>();     

  91.             nsMap.put("ns""http://www.springframework.org/schema/beans");// 加入命名空间     

  92.             XPath xsub = document.createXPath("//ns:beans/ns:bean");// 创建beans/bean查询路径     

  93.             xsub.setNamespaceURIs(nsMap);// 设置命名空间     

  94.             List<Element> beans = xsub.selectNodes(document);// 获取文档下所有bean节点     

  95.             for (Element element : beans) {     

  96.                 String id = element.attributeValue("id");// 获取id属性值     

  97.                 String clazz = element.attributeValue("class"); // 获取class属性值     

  98.                 System.out.println(id + " = " + clazz);  

  99.                 BeanDefinition beanDefine = new BeanDefinition(id, clazz);     

  100.                 XPath propertysub = element.createXPath("ns:property");     

  101.                 propertysub.setNamespaceURIs(nsMap);// 设置命名空间     

  102.                 List<Element> propertys = propertysub.selectNodes(element);     

  103.                 for (Element property : propertys) {     

  104.                     String propertyName = property.attributeValue("name");     

  105.                     String propertyref = property.attributeValue("ref");     

  106.                     System.out.println(propertyName + " = " + propertyref);     

  107.                     PropertyDefinition propertyDefinition = new PropertyDefinition(     

  108.                             propertyName, propertyref);     

  109.                     beanDefine.getPropertys().add(propertyDefinition);     

  110.                 }     

  111.                 beanDefines.add(beanDefine);     

  112.             }     

  113.         } catch (Exception e) {     

  114.             e.printStackTrace();     

  115.         }     

  116.     }     

  117.       

  118.     /**   

  119.      * 获取bean实例   

  120.      */    

  121.     public Object getBean(String beanName) {     

  122.         return this.sigletons.get(beanName);     

  123.     }   

  124.   

  125. }  


测试类SpringTest.java:

Java代码  

  1. package com.luojing.test.testioc;  

  2.   

  3. import com.luojing.test.service.PersonService;  

  4.   

  5. public class SpringTest {  

  6.   

  7.       

  8.     public static void main(String[] args) {  

  9.           

  10.          ItcastClassPathXMLApplicationContext ctx = new ItcastClassPathXMLApplicationContext("applicationContext.xml");   

  11.            

  12.          PersonService ps = (PersonService)ctx.getBean("service");  

  13.               

  14.          ps.save();  

  15.     }  

  16.   

  17. }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值