使用注解实现IoC

DAO接口

 

Java代码   收藏代码
  1. public interface PersonDao {    
  2.     
  3.     public void add();    
  4.     
  5. }    

 

 

实现类

 

Java代码   收藏代码
  1. package cn.leam.dao.impl;    
  2.     
  3. import cn.leam.dao.PersonDao;    
  4.     
  5. public class PersonDaoBean implements PersonDao {    
  6.     public void add(){    
  7.         System.out.println("执行add()方法");    
  8.     }    
  9. }    

 

 

服务接口

Java代码   收藏代码
  1. public interface PersonService {    
  2.     
  3.     public void save();    
  4.     
  5. }    
 

服务实现类

Java代码   收藏代码
  1. public class PersonServiceBean implements PersonService {    
  2.     @LeamResource private PersonDao personDao;    
  3.         
  4.     public PersonDao getPersonDao() {    
  5.         return personDao;    
  6.     }    
  7.     
  8.     public void setPersonDao(PersonDao personDao) {    
  9.         this.personDao = personDao;    
  10.     }    
  11.         
  12.     public void save(){    
  13.         personDao.add();    
  14.     }    
  15. }    

 

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.        xsi:schemaLocation="http://www.springframework.org/schema/beans  
  6.            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
  7.            http://www.springframework.org/schema/context   
  8. <!--需要加上注解-->  
  9. http://www.springframework.org/schema/context/spring-context-2.5.xsd">  
  10.           
  11. <!--需要加上注解标签-->  
  12. <context:annotation-config/>  
  13.                <bean id="personDao" class="cn.leam.dao.impl.PersonDaoBean"></bean>    
  14.               <bean id="personService" class="cn.leam.service.impl.PersonServiceBean">    
  15.                <!--这里把xml定义的属性去掉 我们使用注解获取   
  16.                   <property name="personDao" ref="personDao"></property>  -->  
  17.               </bean>    
  18.     </beans>    

 

下面模拟spring对xml配置的类进行实例化

 

存放属性的对象

 

Java代码   收藏代码
  1. public class prosDefinition {    
  2.     private String name;    
  3.     private String ref;    
  4.         
  5.     public ProsDefinition(String name, String ref) {    
  6.         this.name = name;    
  7.         this.ref = ref;    
  8.     }    
  9.         
  10.     public String getName() {    
  11.         return name;    
  12.     }    
  13.     public void setName(String name) {    
  14.         this.name = name;    
  15.     }    
  16.     public String getRef() {    
  17.         return ref;    
  18.     }    
  19.     public void setRef(String ref) {    
  20.         this.ref = ref;    
  21.     }    
  22.         
  23. }    

 

存放bean的 对象

 

Java代码   收藏代码
  1. public class Definition {    
  2.     private String id;    
  3.     private String className;    
  4.     private List<ProsDefinition> propertys = new ArrayList<ProsDefinition>();    
  5.         
  6.     public Definition(String id, String className) {    
  7.         this.id = id;    
  8.         this.className = className;    
  9.     }    
  10.     public String getId() {    
  11.         return id;    
  12.     }    
  13.     public void setId(String id) {    
  14.         this.id = id;    
  15.     }    
  16.     public String getClassName() {    
  17.         return className;    
  18.     }    
  19.     public void setClassName(String className) {    
  20.         this.className = className;    
  21.     }    
  22.     public List<PropertyDefinition> getPropertys() {    
  23.         return propertys;    
  24.     }    
  25.     public void setPropertys(List<PropertyDefinition> propertys) {    
  26.         this.propertys = propertys;    
  27.     }    
  28.         
  29. }    

 

加上注解

Java代码   收藏代码
  1. @Retention(RetentionPolicy.RUNTIME)  
  2. @Target({ElementType.FIELD, ElementType.METHOD})  
  3. public @interface LeamResource {  
  4.     public String name() default "";  
  5. }  
 

 

这里是关键点  所有代码都在这里    使用dom4j 解析xml文件中的bean  并获取id和class  再判断元素中是否有引用元素对其一并获取出来存放才Map中 利用java反射一个一个进行实例化

 

Java代码   收藏代码
  1.    /**  
  2.     * 学习版容器  
  3.     *  
  4.     */    
  5.    public class LeamClassPathXMLApplicationContext {    
  6.        private List<Definition> beanDefines = new ArrayList<Definition>();    
  7.        private Map<String, Object> sigletons = new HashMap<String, Object>();    
  8.            
  9.        public LeamClassPathXMLApplicationContext(String filename){    
  10.            this.readXML(filename);    
  11.            this.instanceBeans();    
  12.            this.annotationInject();  
  13.            this.injectObject();    
  14.        }    
  15.        /**  
  16.         * 为bean对象的属性注入值  
  17.         */    
  18.        private void injectObject() {    
  19.            for(Definition beanDefinition : beanDefines){    
  20.                Object bean = sigletons.get(beanDefinition.getId());    
  21.                if(bean!=null){    
  22.                    try {    
  23.                        PropertyDescriptor[] ps =   
  24.                    Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();    
  25.                 for(ProsDefinition propertyDefinition : beanDefinition.getPropertys()){    
  26.                            for(PropertyDescriptor properdesc : ps){    
  27.                              if(propertyDefinition.getName().equals(properdesc.getName())){    
  28.                   Method setter = properdesc.getWriteMethod();//获取属性的setter方法  
  29.                                    if(setter!=null){    
  30.                      Object value = sigletons.get(propertyDefinition.getRef());    
  31.                                        setter.setAccessible(true);    
  32.                                        setter.invoke(bean, value);//把引用对象注入到属性    
  33.                                    }    
  34.                                    break;    
  35.                                }    
  36.                            }    
  37.                        }    
  38.                    } catch (Exception e) {    
  39.                    }    
  40.                }    
  41.            }    
  42.        }    
  43.        /**  
  44.         * 完成bean的实例化  
  45.         */    
  46.        private void instanceBeans() {    
  47.            for(Definition beanDefinition : beanDefines){    
  48.                try {    
  49.                    if(beanDefinition.getClassName()!=null && !""  
  50.                                          .equals(beanDefinition.getClassName().trim()))    
  51.                                  sigletons.put(beanDefinition.getId(),     
  52.                               Class.forName(beanDefinition.getClassName()).newInstance());    
  53.                } catch (Exception e) {    
  54.                    e.printStackTrace();    
  55.                }    
  56.            }    
  57.                
  58.        }    
  59.        /**  
  60.         * 读取xml配置文件  
  61.         * @param filename  
  62.         */    
  63.        private void readXML(String filename) {    
  64.               SAXReader saxReader = new SAXReader();       
  65.                Document document=null;       
  66.                try{    
  67.                 URL xmlpath = this.getClass().getClassLoader().getResource(filename);    
  68.                 document = saxReader.read(xmlpath);    
  69.                 Map<String,String> nsMap = new HashMap<String,String>();    
  70.         nsMap.put("ns","http://www.springframework.org/schema/beans");//加入命名空间    
  71.       XPath xsub = document.createXPath("//ns:beans/ns:bean");//创建beans/bean查询路径    
  72.            xsub.setNamespaceURIs(nsMap);//设置命名空间    
  73.       List<Element> beans = xsub.selectNodes(document);//获取文档下所有bean节点     
  74.                 for(Element element: beans){    
  75.                    String id = element.attributeValue("id");//获取id属性值    
  76.        String clazz = element.attributeValue("class"); //获取class属性值            
  77.                    Definition beanDefine = new Definition(id, clazz);    
  78.                    XPath propertysub =  element.createXPath("ns:property");    
  79.                    propertysub.setNamespaceURIs(nsMap);//设置命名空间    
  80.                    List<Element> propertys = propertysub.selectNodes(element);    
  81.                    for(Element property : propertys){                      
  82.       String propertyName = property.attributeValue("name");//元素内部引用的属性也获取    
  83.                        String propertyref = property.attributeValue("ref");    
  84.    ProsDefinition propertyDefinition = new ProsDefinition(propertyName, propertyref);    
  85.                        beanDefine.getPropertys().add(propertyDefinition);    
  86.                    }    
  87.                    beanDefines.add(beanDefine);    
  88.                 }     
  89.                }catch(Exception e){       
  90.                    e.printStackTrace();    
  91.                }    
  92.        }    
  93.        /**  
  94.         * 获取bean实例  
  95.         * @param beanName  
  96.         * @return  
  97.         */    
  98.        public Object getBean(String beanName){    
  99.            return this.sigletons.get(beanName);    
  100.        }    
  101.    }    
  102.   
  103.   
  104.   
  105. **  
  106.  * 通过注解实现注入依赖对象  
  107.  */  
  108. private void annotationInject() {  
  109.     for(String beanName : sigletons.keySet()){  
  110.         Object bean = sigletons.get(beanName);  
  111.         if(bean!=null){  
  112.             try {  
  113.                 PropertyDescriptor[] ps =  
  114.                Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();  
  115.                 for(PropertyDescriptor properdesc : ps){  
  116.             Method setter = properdesc.getWriteMethod();//获取属性的setter方法  
  117.                                        //如果是用了注解 将在set方法注入进去  
  118.                 if(setter!=null && setter.isAnnotationPresent(LeamResource.class)){  
  119.                 LeamResource resource = setter.getAnnotation(LeamResource.class);  
  120.                         Object value = null;  
  121.                         if(resource.name()!=null && !"".equals(resource.name())){  
  122.                             value = sigletons.get(resource.name());  
  123.                         }else{  
  124.                             value = sigletons.get(properdesc.getName());  
  125.                             if(value==null){  
  126.                                 for(String key : sigletons.keySet()){  
  127.                                     if(properdesc.getPropertyType().  
  128.                                         isAssignableFrom(sigletons.get(key).getClass())){  
  129.                                         value = sigletons.get(key);  
  130.                                         break;  
  131.                                     }  
  132.                                 }  
  133.                             }                                 
  134.                         }  
  135.                         setter.setAccessible(true);允许访问私有字段  
  136.                         setter.invoke(bean, value);//把引用对象注入到属性  
  137.                     }  
  138.                 }  
  139.                 Field[] fields = bean.getClass().getDeclaredFields();  
  140.                 for(Field field : fields){  
  141.                     if(field.isAnnotationPresent(LeamResource.class)){  
  142.                 LeamResource resource = field.getAnnotation(LeamResource.class);  
  143.                         Object value = null;  
  144.                         if(resource.name()!=null && !"".equals(resource.name())){  
  145.                             value = sigletons.get(resource.name());  
  146.                         }else{  
  147.                             value = sigletons.get(field.getName());  
  148.                             if(value==null){  
  149.                                 for(String key : sigletons.keySet()){  
  150.                                     if(field.getType().  
  151.                                       isAssignableFrom(sigletons.get(key).getClass())){  
  152.                                         value = sigletons.get(key);  
  153.                                         break;  
  154.                                     }  
  155.                                 }  
  156.                             }                                 
  157.                         }  
  158.                         field.setAccessible(true);//允许访问private字段  
  159.                         field.set(bean, value);  
  160.                     }  
  161.                 }  
  162.             } catch (Exception e) {  
  163.                 e.printStackTrace();  
  164.             }  
  165.         }  
  166.     }  
  167. }  

 

 

 

Java代码   收藏代码
  1. public class SpringTest {    
  2.     
  3.     @BeforeClass    
  4.     public static void setUpBeforeClass() throws Exception {    
  5.     }    
  6.     
  7.     @Test public void instanceSpring(){    
  8.         LeamClassPathXMLApplicationContext ctx = new    
  9.                                       LeamClassPathXMLApplicationContext("beans.xml");    
  10.         PersonService personService = (PersonService)ctx.getBean("personService");    
  11.         personService.save();           
  12.     }    
  13. }    

 

 

最终输出

 

"执行add()方法" 说明实例化成功  否则 出现空指针异常

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值