Spring学习笔记(6)----编码剖析Spring依赖注入的原理

在Spring学习笔记(3)中剖析了Spring管理Bean的原理,下面解释下Spring依赖注入的原理

在进行依赖注入时,我们的配置文件如下配置:

Xml代码
  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.     xmlns:context="http://www.springframework.org/schema/context"  
  5.     xmlns:tx="http://www.springframework.org/schema/tx"  
  6.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd   
  7.                 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd   
  8.                 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">  
  9.     <bean id="mySqlDAO" class="com.szy.spring.dao.UserDAO4MySqlImpl"/>  
  10.     <bean id="oracleDAO" class="com.szy.spring.dao.UserDAO4OracleImpl"/>  
  11.     <bean id="userService" class="com.szy.spring.service.UserServiceImpl">  
  12.         <!--构造方法注入     
  13.             <property name="userDAO" ref="mySqlDAO"></property>  
  14.         -->  
  15.         <property name="userDAO" ref="oracleDAO"></property>  
  16.     </bean>  
  17. </beans>  

 根据配置文件信息,我们首先需要建立一个Bean类,用来保存bean节点的信息:

Java代码
  1. package com.szy.spring.bean;   
  2.   
  3. import java.util.List;   
  4.   
  5. public class Bean   
  6. {   
  7.     private String id;      
  8.     private String className;    
  9.     private List<Property> propertyList;   
  10.     public Bean(String id, String className, List<Property> propertyList)   
  11.     {   
  12.         super();   
  13.         this.id = id;   
  14.         this.className = className;   
  15.         this.propertyList = propertyList;   
  16.     }   
  17.     public String getId()      
  18.     {      
  19.         return id;      
  20.     }      
  21.     public void setId(String id)      
  22.     {      
  23.         this.id = id;      
  24.     }      
  25.     public String getClassName()      
  26.     {      
  27.         return className;      
  28.     }      
  29.     public void setClassName(String className)      
  30.     {      
  31.         this.className = className;      
  32.     }   
  33.     public List<Property> getPropertyList()   
  34.     {   
  35.         return propertyList;   
  36.     }   
  37.     public void setPropertyList(List<Property> propertyList)   
  38.     {   
  39.         this.propertyList = propertyList;   
  40.     }      
  41. }  

 此外,由于bean下存在property信息,因此我们还需要建立property类

Java代码
  1. package com.szy.spring.bean;   
  2.   
  3. public class Property   
  4. {   
  5.     private String name;   
  6.     private String ref;   
  7.        
  8.     public Property(String name, String ref)   
  9.     {   
  10.         super();   
  11.         this.name = name;   
  12.         this.ref = ref;   
  13.     }   
  14.     public String getName()   
  15.     {   
  16.         return name;   
  17.     }   
  18.     public void setName(String name)   
  19.     {   
  20.         this.name = name;   
  21.     }   
  22.     public String getRef()   
  23.     {   
  24.         return ref;   
  25.     }   
  26.     public void setRef(String ref)   
  27.     {   
  28.         this.ref = ref;   
  29.     }   
  30.        
  31. }  

在Spring学习笔记(3)中,我们在读取xml文件时bean节点下面是不存在property节点的,因此在这里我们需要修改readXML()方法:

Java代码
  1. /**  
  2.      * 读取xml配置文件  
  3.      * @param fileName 配置文件名  
  4.      */  
  5.     private void readXML(String fileName)   
  6.     {   
  7.         // 寻找配置文件   
  8.         URL xmlPath = this.getClass().getClassLoader().getResource(fileName);   
  9.         Document doc = null;   
  10.         Element root = null;   
  11.         try  
  12.         {   
  13.             SAXBuilder sb = new SAXBuilder(false);   
  14.             doc = sb.build(new FileInputStream(new File(xmlPath.toURI())));   
  15.             // 设置命名空间      
  16.             Namespace xhtml = Namespace.getNamespace("xhtml",   
  17.                     "http://www.springframework.org/schema/beans");   
  18.             root = doc.getRootElement(); // 获取根元素      
  19.             List<Element> bList = root.getChildren("bean", xhtml); //获取全部bean节点      
  20.             for (Element beanElement : bList)// 遍历节点,取得每个节点的属性      
  21.             {   
  22.                 String id = beanElement.getAttributeValue("id");   
  23.                 String className = beanElement.getAttributeValue("class");   
  24.                 //获得每个bean下面的属性   
  25.                 List<Element> pList = beanElement   
  26.                         .getChildren("property", xhtml);   
  27.                 List<Property> propertyList = new ArrayList<Property>(); //存储属性信息   
  28.                 if (pList.size() > 0//如果存在属性   
  29.                 {   
  30.                     for (Element propertyElement : pList) //遍历属性节点   
  31.                     {   
  32.                         String name = propertyElement.getAttributeValue("name");   
  33.                         String ref = propertyElement.getAttributeValue("ref");   
  34.                         Property property = new Property(name, ref);   
  35.                         propertyList.add(property); //保存属性节点   
  36.                     }   
  37.                 }   
  38.                 Bean bean = new Bean(id, className, propertyList);   
  39.                 beanList.add(bean);   
  40.             }   
  41.   
  42.         } catch (Exception e)   
  43.         {   
  44.             e.printStackTrace();   
  45.         }   
  46.     }  

 读取完配置文件后我们还是需要对bean进行实例化的,这方法和Spring学习笔记(3)中的instanceBeans()方法一样。下面就是我们需要给bean属性进行注入,实现方法如下:

Java代码
  1. /**  
  2.      * 为bean对象的属性注入值  
  3.      */  
  4.     public void injectObject()   
  5.     {   
  6.         for (Bean bean : beanList)   
  7.         {   
  8.             Object object = beanObject.get(bean.getId()); //获取bean的实例   
  9.             if (object != null)   
  10.             {   
  11.                 try  
  12.                 {   
  13.                     PropertyDescriptor[] ps = Introspector.getBeanInfo(   
  14.                             object.getClass()).getPropertyDescriptors();  //取得bean的属性描述   
  15.                     for (Property property : bean.getPropertyList())  //获取bean节点的属性   
  16.                     {   
  17.                         for (PropertyDescriptor properdesc : ps)     
  18.                         {   
  19.                             if (property.getName().equals(properdesc.getName()))   
  20.                             {   
  21.                                 Method setter = properdesc.getWriteMethod();//获取属性的setter方法 ,private   
  22.                                 if (setter != null)   
  23.                                 {   
  24.                                     Object value = beanObject.get(property.getRef());  //取得值   
  25.                                     setter.setAccessible(true);  //设置为允许访问   
  26.                                     setter.invoke(object, value);//把引用对象注入到属性   
  27.                                 }   
  28.                                 break;   
  29.                             }   
  30.                         }   
  31.                     }   
  32.                 } catch (Exception e)   
  33.                 {   
  34.                     e.printStackTrace();   
  35.                 }   
  36.             }   
  37.         }  

 

我们进行测试:

Java代码
  1. MyClassPathXMLApplicationContext ctx=new MyClassPathXMLApplicationContext("applicationContext.xml");      
  2.         UserService service=(UserService)ctx.getBean("userService");   
  3.         service.show();  

 

运行输出

结果代码
  1. OracleDAO Implement  

 上面仅是简单的演示了Spring依赖注入的原理,但是在实际操作中还需要考虑很对其它因素,在此就不进行讨论了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值