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.     }    
7.

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

Java代码


1. <bean id="animal" class="phz.springframework.test.Cat">     
2.         <property name="name">     
3.             <value>kitty</value>     
4.         </property>     
5. </bean>    
6.


他有一个类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. }    
10.

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

Java代码

1. public interface Animal {     
2.     public void say();     
3. }    
4.


很明显上面的代码输出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这个类。我们都知道Spring可以注入基本类型,而且可以注入像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>    
    13.  
     
     Spring运作机制中是怎样保存上面的配置呢?,代码如下:
     
     
    1.  
    2. if (beanProperty.element("map") != null) {  
    3.      Map<String, Object> propertiesMap = new HashMap<String, Object>();  
    4.      Element propertiesListMap = (Element) beanProperty  
    5.        .elements().get(0);  
    6.      Iterator<?> propertiesIterator = propertiesListMap 
    7.        .elements().iterator();  
    8.      while (propertiesIterator.hasNext()) {  
    9.       Element vet = (Element) propertiesIterator.next();  
    10.       if (vet.getName().equals("entry")) {  
    11.        String key = vet.attributeValue("key");  
    12.        Iterator<?> valuesIterator = vet.elements()  
    13.          .iterator();  
    14.        while (valuesIterator.hasNext()) {  
    15.         Element value = (Element) valuesIterator.next();  
    16.         if (value.getName().equals("value")) {  
    17.          propertiesMap.put(key, value.getText());  
    18.         }  
    19.         if (value.getName().equals("ref")) {  
    20.          propertiesMap.put(key, new String[] { value  
    21.            .attributeValue("bean") });  
    22.         }  
    23.        }  
    24.       }  
    25.      }  
    26.      bean.getProperties().put(name, propertiesMap);  
    27.     }

    接下来就进入最核心部分了,让我们看看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.     }    
      16.


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

      Java代码

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


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

      Java代码

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

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