首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

懂得Spring依赖注入(模拟Spring容器)

2012-08-24 
理解Spring依赖注入(模拟Spring容器)仿spring容器 ,也就是传智播客容器 ItcastClassPathXMLApplicationCon

理解Spring依赖注入(模拟Spring容器)

仿spring容器 ,也就是传智播客容器 ItcastClassPathXMLApplicationContext

import java.beans.Introspector;   import java.beans.PropertyDescriptor;   import java.lang.reflect.Field;   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.apache.commons.beanutils.ConvertUtils;   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.annotationInject();           this.injectObject();       }       /**       * 通过注解实现注入依赖对象       */       private void annotationInject() {           for(String beanName : sigletons.keySet()){               Object bean = sigletons.get(beanName);               if(bean!=null){                   try {                       PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();                       for(PropertyDescriptor properdesc : ps){                           Method setter = properdesc.getWriteMethod();//获取属性的setter方法                           /*如果setter方法不为空,并且上面有注解*/                           if(setter!=null && setter.isAnnotationPresent(ItcastResource.class)){                               /*得到注解*/                               ItcastResource resource = setter.getAnnotation(ItcastResource.class);                               Object value = null;                               //如果注解的name属性不为空,也就是这种情况    @ItcastResource(name="persionDao")                               if(resource.name()!=null && !"".equals(resource.name())){                                   value = sigletons.get(resource.name());                               }else{                               /*如果注解的name为空,则根据属性的名字来得到bean*/                                   value = sigletons.get(properdesc.getName());                                   if(value==null)                                   {                                       /*如果的得到的bean为空,则根据key遍历容器中所有的bean,如果发现和属性类型相同的bean,就开始注入*/                                       for(String key : sigletons.keySet()){                                           if(properdesc.getPropertyType().isAssignableFrom(sigletons.get(key).getClass())){                                               value = sigletons.get(key);                                               break;                                           }                                       }                                   }                                                              }                               setter.setAccessible(true);                               setter.invoke(bean, value);//把引用对象注入到属性                           }                       }                       /*对字段处理,也就是字段上有注解的情况*/                       Field[] fields = bean.getClass().getDeclaredFields();                       for(Field field : fields){                           if(field.isAnnotationPresent(ItcastResource.class)){                               ItcastResource resource = field.getAnnotation(ItcastResource.class);                               Object value = null;                               if(resource.name()!=null && !"".equals(resource.name())){                                   value = sigletons.get(resource.name());                               }else{                                   value = sigletons.get(field.getName());                                   if(value==null){                                       for(String key : sigletons.keySet()){                                           if(field.getType().isAssignableFrom(sigletons.get(key).getClass())){                                               value = sigletons.get(key);                                               break;                                           }                                       }                                   }                                                              }                               field.setAccessible(true);//允许访问private字段                               field.set(bean, value);                           }                       }                   } catch (Exception e) {                       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();                       for(PropertyDefinition propertyDefinition : beanDefinition.getPropertys()){                           for(PropertyDescriptor properdesc : ps){                               if(propertyDefinition.getName().equals(properdesc.getName())){                                   Method setter = properdesc.getWriteMethod();//获取属性的setter方法 ,private                                   if(setter!=null){                                       Object value = null;                                       if(propertyDefinition.getRef()!=null && !"".equals(propertyDefinition.getRef().trim())){                                           value = sigletons.get(propertyDefinition.getRef());                                       }else{                                           value = ConvertUtils.convert(propertyDefinition.getValue(), properdesc.getPropertyType());                                       }                                       setter.setAccessible(true);                                       setter.invoke(bean, value);//把引用对象注入到属性                                   }                                   break;                               }                           }                       }                   } catch (Exception e) {                   }               }           }       }       /**       * 完成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) {                   e.printStackTrace();               }           }                  }       /**       * 读取xml配置文件       * @param filename       */       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属性值                           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");                       String propertyValue = property.attributeValue("value");                       PropertyDefinition propertyDefinition = new PropertyDefinition(propertyName, propertyref, propertyValue);                       beanDefine.getPropertys().add(propertyDefinition);                   }                   beanDefines.add(beanDefine);                }                }catch(Exception e){                      e.printStackTrace();               }       }       /**       * 获取bean实例       * @param beanName       * @return       */       public Object getBean(String beanName){           return this.sigletons.get(beanName);       }   }   

?

? 测试:
ItcastClassPathXMLApplicationContext ctx = new ItcastClassPathXMLApplicationContext("beans.xml");
PersionSevice ps=(PersionSevice)ctx.getBean("persionServiceBean");
ps.save();

热点排行