• spring 注入原理


    我们先从最常见的例子开始吧 

    Java代码 复制代码
    1. public static void main(String[] args) {   
    2.         ApplicationContext context = new FileSystemXmlApplicationContext(   
    3.                 "applicationContext.xml");   
    4.         Animal animal = (Animal) context.getBean("animal");   
    5.         animal.say();   
    6.     }  


    这段代码你一定很熟悉吧,不过还是让我们分析一下它吧,首先是applicationContext.xml 

    Java代码 复制代码
    1. <bean id="animal" class="phz.springframework.test.Cat">   
    2.         <property name="name" value="kitty" />   
    3.     </bean>  


    他有一个类phz.springframework.test.Cat 

    Java代码 复制代码
    1. public class Cat implements Animal {   
    2.     private String name;   
    3.     public void say() {   
    4.         System.out.println("I am " + name + "!");   
    5.     }   
    6.     public void setName(String name) {   
    7.         this.name = name;   
    8.     }   
    9. }  


    实现了phz.springframework.test.Animal接口 

    Java代码 复制代码
    1. public interface Animal {   
    2.     public void say();   
    3. }  


    很明显上面的代码输出I am kitty! 

    那么到底Spring是如何做到的呢? 
    接下来就让我们自己写个Spring 来看看Spring 到底是怎么运行的吧! 

    首先,我们定义一个Bean类,这个类用来存放一个Bean拥有的属性 

    Java代码 复制代码
    1. /* Bean Id */  
    2.     private String id;   
    3.     /* Bean Class */  
    4.     private String type;   
    5.     /* Bean Property */  
    6.     private Map<String, Object> properties = new HashMap<String, Object>();  


    一个Bean包括id,type,和Properties。 

    接下来Spring 就开始加载我们的配置文件了,将我们配置的信息保存在一个HashMap中,HashMap的key就是Bean 的 Id ,HasMap 的value是这个Bean,只有这样我们才能通过context.getBean("animal")这个方法获得Animal这个类。我们都知道Spirng可以注入基本类型,而且可以注入像List,Map这样的类型,接下来就让我们以Map为例看看Spring是怎么保存的吧 

    Map配置可以像下面的 

    Java代码 复制代码
    1. <bean id="test" class="Test">   
    2.         <property name="testMap">   
    3.             <map>   
    4.                 <entry key="a">   
    5.                     <value>1</value>   
    6.                 </entry>   
    7.                 <entry key="b">   
    8.                     <value>2</value>   
    9.                 </entry>   
    10.             </map>   
    11.         </property>   
    12.     </bean>  


    Spring是怎样保存上面的配置呢?,代码如下: 

    Java代码 复制代码
    1. if (beanProperty.element("map") != null) {   
    2.                     Map<String, Object> propertiesMap = new HashMap<String, Object>();   
    3.                     Element propertiesListMap = (Element) beanProperty   
    4.                             .elements().get(0);   
    5.                     Iterator<?> propertiesIterator = propertiesListMap   
    6.                             .elements().iterator();   
    7.                     while (propertiesIterator.hasNext()) {   
    8.                         Element vet = (Element) propertiesIterator.next();   
    9.                         if (vet.getName().equals("entry")) {   
    10.                             String key = vet.attributeValue("key");   
    11.                             Iterator<?> valuesIterator = vet.elements()   
    12.                                     .iterator();   
    13.                             while (valuesIterator.hasNext()) {   
    14.                                 Element value = (Element) valuesIterator.next();   
    15.                                 if (value.getName().equals("value")) {   
    16.                                     propertiesMap.put(key, value.getText());   
    17.                                 }   
    18.                                 if (value.getName().equals("ref")) {   
    19.                                     propertiesMap.put(key, new String[] { value   
    20.                                             .attributeValue("bean") });   
    21.                                 }   
    22.                             }   
    23.                         }   
    24.                     }   
    25.                     bean.getProperties().put(name, propertiesMap);   
    26.                 }  



    接下来就进入最核心部分了,让我们看看Spring 到底是怎么依赖注入的吧,其实依赖注入的思想也很简单,它是通过反射机制实现的,在实例化一个类时,它通过反射调用类中set方法将事先保存在HashMap中的类属性注入到类中。让我们看看具体它是怎么做的吧。 
    首先实例化一个类,像这样 

    Java代码 复制代码
    1. public static Object newInstance(String className) {   
    2.         Class<?> cls = null;   
    3.         Object obj = null;   
    4.         try {   
    5.             cls = Class.forName(className);   
    6.             obj = cls.newInstance();   
    7.         } catch (ClassNotFoundException e) {   
    8.             throw new RuntimeException(e);   
    9.         } catch (InstantiationException e) {   
    10.             throw new RuntimeException(e);   
    11.         } catch (IllegalAccessException e) {   
    12.             throw new RuntimeException(e);   
    13.         }   
    14.         return obj;   
    15.     }  


    接着它将这个类的依赖注入进去,像这样 

    Java代码 复制代码
    1. public static void setProperty(Object obj, String name, String value) {   
    2.         Class<? extends Object> clazz = obj.getClass();   
    3.         try {   
    4.             String methodName = returnSetMthodName(name);   
    5.             Method[] ms = clazz.getMethods();   
    6.             for (Method m : ms) {   
    7.                 if (m.getName().equals(methodName)) {   
    8.                     if (m.getParameterTypes().length == 1) {   
    9.                         Class<?> clazzParameterType = m.getParameterTypes()[0];   
    10.                         setFieldValue(clazzParameterType.getName(), value, m,   
    11.                                 obj);   
    12.                         break;   
    13.                     }   
    14.                 }   
    15.             }   
    16.         } catch (SecurityException e) {   
    17.             throw new RuntimeException(e);   
    18.         } catch (IllegalArgumentException e) {   
    19.             throw new RuntimeException(e);   
    20.         } catch (IllegalAccessException e) {   
    21.             throw new RuntimeException(e);   
    22.         } catch (InvocationTargetException e) {   
    23.             throw new RuntimeException(e);   
    24.         }   
    25. }  


    最后它将这个类的实例返回给我们,我们就可以用了。我们还是以Map为例看看它是怎么做的,我写的代码里面是创建一个HashMap并把该HashMap注入到需要注入的类中,像这样, 

    Java代码 复制代码
    1. if (value instanceof Map) {   
    2.                 Iterator<?> entryIterator = ((Map<?, ?>) value).entrySet()   
    3.                         .iterator();   
    4.                 Map<String, Object> map = new HashMap<String, Object>();   
    5.                 while (entryIterator.hasNext()) {   
    6.                     Entry<?, ?> entryMap = (Entry<?, ?>) entryIterator.next();   
    7.                     if (entryMap.getValue() instanceof String[]) {   
    8.                         map.put((String) entryMap.getKey(),   
    9.                                 getBean(((String[]) entryMap.getValue())[0]));   
    10.                     }   
    11.                 }   
    12.                 BeanProcesser.setProperty(obj, property, map);   
    13.             }  


    好了,这样我们就可以用Spring 给我们创建的类了,是不是也不是很难啊?当然Spring能做到的远不止这些,这个示例程序仅仅提供了Spring最核心的依赖注入功能中的一部分。

  • 相关阅读:
    使用通配符查询
    使用聚合函数查询
    有趣的图标
    利用Office Chart 制作柱图(一个柱子)
    众多select
    对象不能从 DBNull 转换为其他类型。
    使用谓词进行查询
    使用数学函数查询
    学生信息表 通过选择年级和班级得到详细的学生信息名单
    使用时间函数查询
  • 原文地址:https://www.cnblogs.com/zhaoxd/p/3077783.html
Copyright © 2020-2023  润新知