Spring2.5学习2.2_编码剖析Spring依赖注入原理

来源:互联网 发布:mac ox版本升级mac os 编辑:程序博客网 时间:2024/05/29 02:26

为了便于理解Spring属性注入,这里来模拟Spring容器是如何实现将PersonDaoBean注入到PersonServiceBean的。

所需jar包:下载地址http://download.csdn.net/detail/jeofey/8747927


PersonDaoBean.java

[java] view plaincopy
  1. package xjj.dao.impl;  
  2.   
  3. import xjj.dao.PersonDao;  
  4.   
  5. public class PersonDaoBean implements PersonDao {  
  6.     public void add(){  
  7.         System.out.println("执行PersonDaoBean中的add()方法");  
  8.     }  
  9. }  


PersonDao.java接口

[java] view plaincopy
  1. package xjj.dao;  
  2.   
  3. public interface PersonDao {  
  4.   
  5.     public void add();  
  6.   
  7. }  


PersonServiceBean.java

[java] view plaincopy
  1. package xjj.service.impl;  
  2.   
  3. import xjj.dao.PersonDao;  
  4. import xjj.service.PersonService;  
  5.   
  6. public class PersonServiceBean implements PersonService {  
  7.     private PersonDao personDao;  
  8.       
  9.     public PersonDao getPersonDao() {  
  10.         return personDao;  
  11.     }  
  12.   
  13.     public void setPersonDao(PersonDao personDao) {  
  14.         this.personDao = personDao;  
  15.     }  
  16.       
  17.     public void save(){  
  18.         personDao.add();  
  19.     }  
  20. }  


PersonService.java接口

[java] view plaincopy
  1. package xjj.service;  
  2.   
  3. public interface PersonService {  
  4.   
  5.     public void save();  
  6.   
  7. }  

BeanDefinition.java

[java] view plaincopy
  1. package junit.test;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. public class BeanDefinition {  
  7.     private String id;  
  8.     private String className;  
  9.     private List<PropertyDefinition> propertys = new ArrayList<PropertyDefinition>();  
  10.       
  11.     public BeanDefinition(String id, String className) {  
  12.         this.id = id;  
  13.         this.className = className;  
  14.     }  
  15.     public String getId() {  
  16.         return id;  
  17.     }  
  18.     public void setId(String id) {  
  19.         this.id = id;  
  20.     }  
  21.     public String getClassName() {  
  22.         return className;  
  23.     }  
  24.     public void setClassName(String className) {  
  25.         this.className = className;  
  26.     }  
  27.     public List<PropertyDefinition> getPropertys() {  
  28.         return propertys;  
  29.     }  
  30.     public void setPropertys(List<PropertyDefinition> propertys) {  
  31.         this.propertys = propertys;  
  32.     }  
  33.       
  34. }  


PropertyDefinition.java

[java] view plaincopy
  1. package junit.test;  
  2.   
  3. public class PropertyDefinition {  
  4.     private String name;  
  5.     private String ref;  
  6.       
  7.     public PropertyDefinition(String name, String ref) {  
  8.         this.name = name;  
  9.         this.ref = ref;  
  10.     }  
  11.       
  12.     public String getName() {  
  13.         return name;  
  14.     }  
  15.     public void setName(String name) {  
  16.         this.name = name;  
  17.     }  
  18.     public String getRef() {  
  19.         return ref;  
  20.     }  
  21.     public void setRef(String ref) {  
  22.         this.ref = ref;  
  23.     }  
  24.       
  25. }  


XjjClassPathXMLApplicationContext.java

[java] view plaincopy
  1. package junit.test;  
  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. /** 
  18.  * 传智传客版容器 
  19.  * 
  20.  */  
  21. public class XjjClassPathXMLApplicationContext {  
  22.     private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>();  
  23.     private Map<String, Object> sigletons = new HashMap<String, Object>();  
  24.       
  25.     public XjjClassPathXMLApplicationContext(String filename){  
  26.         this.readXML(filename);  
  27.         this.instanceBeans();  
  28.         this.injectObject();  
  29.     }  
  30.     /** 
  31.      * 为bean对象的属性注入值 
  32.      */  
  33.     private void injectObject() {  
  34.         for(BeanDefinition beanDefinition : beanDefines){  
  35.             Object bean = sigletons.get(beanDefinition.getId());  
  36.             if(bean!=null){  
  37.                 try {  
  38.                     PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();  
  39.                     for(PropertyDefinition propertyDefinition : beanDefinition.getPropertys()){  
  40.                         for(PropertyDescriptor properdesc : ps){  
  41.                             if(propertyDefinition.getName().equals(properdesc.getName())){  
  42.                                 Method setter = properdesc.getWriteMethod();//获取属性的setter方法 ,private  
  43.                                 if(setter!=null){  
  44.                                     Object value = sigletons.get(propertyDefinition.getRef());  
  45.                                     setter.setAccessible(true);  
  46.                                     setter.invoke(bean, value);//把引用对象注入到属性  
  47.                                 }  
  48.                                 break;  
  49.                             }  
  50.                         }  
  51.                     }  
  52.                 } catch (Exception e) {  
  53.                 }  
  54.             }  
  55.         }  
  56.     }  
  57.     /** 
  58.      * 完成bean的实例化 
  59.      */  
  60.     private void instanceBeans() {  
  61.         for(BeanDefinition beanDefinition : beanDefines){  
  62.             try {  
  63.                 if(beanDefinition.getClassName()!=null && !"".equals(beanDefinition.getClassName().trim()))  
  64.                     sigletons.put(beanDefinition.getId(), Class.forName(beanDefinition.getClassName()).newInstance());  
  65.             } catch (Exception e) {  
  66.                 e.printStackTrace();  
  67.             }  
  68.         }  
  69.           
  70.     }  
  71.     /** 
  72.      * 读取xml配置文件 
  73.      * @param filename 
  74.      */  
  75.     private void readXML(String filename) {  
  76.            SAXReader saxReader = new SAXReader();     
  77.             Document document=null;     
  78.             try{  
  79.              URL xmlpath = this.getClass().getClassLoader().getResource(filename);  
  80.              document = saxReader.read(xmlpath);  
  81.              Map<String,String> nsMap = new HashMap<String,String>();  
  82.              nsMap.put("ns","http://www.springframework.org/schema/beans");//加入命名空间  
  83.              XPath xsub = document.createXPath("//ns:beans/ns:bean");//创建beans/bean查询路径  
  84.              xsub.setNamespaceURIs(nsMap);//设置命名空间  
  85.              List<Element> beans = xsub.selectNodes(document);//获取文档下所有bean节点   
  86.              for(Element element: beans){  
  87.                 String id = element.attributeValue("id");//获取id属性值  
  88.                 String clazz = element.attributeValue("class"); //获取class属性值          
  89.                 BeanDefinition beanDefine = new BeanDefinition(id, clazz);  
  90.                 XPath propertysub =  element.createXPath("ns:property");  
  91.                 propertysub.setNamespaceURIs(nsMap);//设置命名空间  
  92.                 List<Element> propertys = propertysub.selectNodes(element);  
  93.                 for(Element property : propertys){                    
  94.                     String propertyName = property.attributeValue("name");  
  95.                     String propertyref = property.attributeValue("ref");  
  96.                     PropertyDefinition propertyDefinition = new PropertyDefinition(propertyName, propertyref);  
  97.                     beanDefine.getPropertys().add(propertyDefinition);  
  98.                 }  
  99.                 beanDefines.add(beanDefine);  
  100.              }   
  101.             }catch(Exception e){     
  102.                 e.printStackTrace();  
  103.             }  
  104.     }  
  105.     /** 
  106.      * 获取bean实例 
  107.      * @param beanName 
  108.      * @return 
  109.      */  
  110.     public Object getBean(String beanName){  
  111.         return this.sigletons.get(beanName);  
  112.     }  
  113. }  


SpringTest.java

[java] view plaincopy
  1. package junit.test;  
  2.   
  3. import org.junit.BeforeClass;  
  4. import org.junit.Test;  
  5.   
  6. import xjj.service.PersonService;  
  7.   
  8. public class SpringTest {  
  9.   
  10.     @BeforeClass  
  11.     public static void setUpBeforeClass() throws Exception {  
  12.     }  
  13.   
  14.     @Test public void instanceSpring(){  
  15.         XjjClassPathXMLApplicationContext ctx = new XjjClassPathXMLApplicationContext("beans.xml");  
  16.         PersonService personService = (PersonService)ctx.getBean("personService");  
  17.         personService.save();         
  18.     }  
  19. }  

beans.xml

[html] view plaincopy
  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.            <bean id="personDao" class="xjj.dao.impl.PersonDaoBean"></bean>  
  7.           <bean id="personService" class="xjj.service.impl.PersonServiceBean">  
  8.             <property name="personDao" ref="personDao"></property>  
  9.           </bean>  
  10. </beans>  

结果:


0 0