• 模拟spring框架注入实现原理


    这个我是参见了别人的一些东西,不是原创!

    定义一些抽象的方法:

    package com.huxin.springinject.dao;
    
    public interface Person {
        public void save();
        public void useAxe();
    }
    package com.huxin.springinject.dao;
    
    public interface Axe {
       public void  chop();
       
    }


    实现的一些方法:

    package com.huxin.springinject.dao.impl;
    
    import com.huxin.springinject.dao.Axe;
    import com.huxin.springinject.dao.Person;
    
    public class Chinese implements Person {
    	private Axe axe;	
    	public Axe getAxe() {
    		return axe;
    	}
    
    	public void setAxe(Axe axe) {
    		this.axe = axe;
    	}
    
    	public void save() {
            System.out.println("保存人的方法");
    	}	
    	public void useAxe(){
    		axe.chop();
    	}
    }
    


     

    package com.huxin.springinject.dao.impl;
    
    import com.huxin.springinject.dao.Axe;
    
    public class StoneAxe implements Axe {
    
    	@Override
    	public void chop() {
    	   System.out.println("铁斧头砍柴真慢");
    
    	}
    
    }


    这里是关键spring框架模拟的实现的一些原理!!!

    package junit.test;
    import java.beans.Introspector;
    import java.beans.PropertyDescriptor;
    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 ApplicationContext {
         List<BeanInformation> beansInformation = new ArrayList<BeanInformation>();
         Map<String,Object> singleton = new HashMap<String,Object>();
         
         
         public ApplicationContext(){};
         public ApplicationContext(String filename){
        	 readXml(filename);
        	 initBean();
        	 this.injectObject();
         }
         public void readXml(String filename){
        	 SAXReader saxReader = new SAXReader();
        	 Document document = null;
        	 try{
            	 //使用反射机制,通过文件名加载文件路径
        		 URL xmlPath = this.getClass().getClassLoader().getResource(filename);
        		 
        		 //通过文件路径获得这个文件的document对象
        		 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){
        			 System.out.println(element.attributeValue("id"));
        			 System.out.println(element.attributeValue("class"));
        			 
        			 BeanInformation beanInformation = new BeanInformation();
        			 beanInformation.setId(element.attributeValue("id"));
        			 beanInformation.setName(element.attributeValue("class"));
        			 
        			 XPath xref = element.createXPath("ns:property");//创建properties查询路径
        			 xref.setNamespaceURIs(nsMap);//设置命名空间
        			 
        			 List<Element> propertys = xref.selectNodes(element);
        			 for(Element property : propertys){
        				 PropertyInformation propertyInformation = new PropertyInformation();
        				 propertyInformation.setName(property.attributeValue("name"));
        				 propertyInformation.setRef(property.attributeValue("ref"));
        				 propertyInformation.setValue(property.attributeValue("value"));
        				 beanInformation.getPropertyInformation().add(propertyInformation);
        			 }
        			 beansInformation.add(beanInformation);
        		 }
             } catch(Exception e){
            	 e.printStackTrace();
             }
         }
         
         public void initBean(){
        	 for(BeanInformation beanInformation: beansInformation){
        		 if(beanInformation.getName()!=null && !"".equals(beanInformation.getName())){
        			 //通过反射机制,根据名字初始化这个类
        			try {
    					singleton.put(beanInformation.getId(), Class.forName(beanInformation.getName()).newInstance());
    				} catch (Exception e) {
    					e.printStackTrace();
    				}
        		 }
        	 }
         }
         
         /**
     	 *    关于注入的实现
     	 */
     	private void injectObject() {
     		for(BeanInformation beanInformation : beansInformation){
     			Object bean = singleton.get(beanInformation.getId());
     			if(bean!=null){
     				try {
     					PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
     					for(PropertyInformation propertyInformation : beanInformation.getPropertyInformation()){
     						for(PropertyDescriptor properdesc : ps){
     							if(propertyInformation.getName().equals(properdesc.getName())){
     								Method setter = properdesc.getWriteMethod();//获取属性的setter方法 ,private
     								if(setter!=null){
     									Object value = null;
     									if(propertyInformation.getRef()!=null && !"".equals(propertyInformation.getRef().trim())){
     										value = singleton.get(propertyInformation.getRef());
     									}else{
     										value = ConvertUtils.convert(propertyInformation.getValue(), properdesc.getPropertyType());
     									}
     									setter.setAccessible(true);
     									setter.invoke(bean, value);//把引用对象注入到属性
     								}
     								break;
     							}
     						}
     					}
     				} catch (Exception e) {
     				}
     			}
     		}
     	}
     	
         public Object getBean(String id){
    		 return this.singleton.get(id); 	 
         }
    }
    package junit.test;
    
    import java.util.HashSet;
    import java.util.Set;
    
    public class BeanInformation {
        private String id;
        private String name;
        private Set<PropertyInformation> propertyInformation = new HashSet<PropertyInformation>();
    	public String getId() {
    		return id;
    	}
    	public void setId(String id) {
    		this.id = id;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public Set<PropertyInformation> getPropertyInformation() {
    		return propertyInformation;
    	}
    	public void setPropertyInformation(Set<PropertyInformation> propertyInformation) {
    		this.propertyInformation = propertyInformation;
    	}
    }
    package junit.test;
    
    public class PropertyInformation {
        private String name;
        private String ref;
        private String value;
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public String getRef() {
    		return ref;
    	}
    	public void setRef(String ref) {
    		this.ref = ref;
    	}
    	public String getValue() {
    		return value;
    	}
    	public void setValue(String value) {
    		this.value = value;
    	}
    }

    测试类:

    package junit.test;
    
    import com.huxin.springinject.dao.Person;
    
    public class Test {
    	public static void main(String[] args) {
    		ApplicationContext ac = new ApplicationContext("applicationContext.xml");
    		Person person = (Person)ac.getBean("chinese");
    		person.save();
    		person.useAxe();
    	}
    }
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"  
           xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
               http://www.springframework.org/schema/context 
               http://www.springframework.org/schema/context/spring-context-3.0.xsd">
           
          
          <bean id="chinese"  class="com.huxin.springinject.dao.impl.Chinese">
             <property name="axe" ref="stoneAxe"/>
          </bean>
          <bean id="stoneAxe" class="com.huxin.springinject.dao.impl.StoneAxe"/>
    </beans>

    补充说明: 需要导入dom4j相应的辅助包和junit辅助包!

  • 相关阅读:
    验证LeetCode Surrounded Regions 包围区域的DFS方法
    Qt Package Project 打包发布程序
    [LeetCode] Missing Number 丢失的数字
    [CareerCup] 6.4 Blue Eyes People on Island 岛上的蓝眼人
    [CareerCup] 6.3 Water Jug 水罐问题
    [CareerCup] 6.2 Dominos on Chess Board 棋盘上的多米诺
    [CareerCup] 6.1 Find Heavy Bottle 寻找重瓶子
    [CareerCup] 5.8 Draw Horizonatal Line 画横线
    Print or Cout an Unsigned Char Variable 打印无符号字符
    Kinect 学习链接
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3153376.html
Copyright © 2020-2023  润新知