Spring核心之IOC&反射

IOC思想:Spring容器来实现相互依赖对象的创建,协调工作。对象只需要关心业务逻辑本身就好了。从这方面来说,对象如何得到他的协作对象的责任被反转了(IOC、DI)。控制反转就是获得依赖对象的方式反转了由Spring来负责控制对象的生命周期和对象间的关系

IOC(控制反转)之中的核心是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。

那么DI是如何实现的呢? Java 1.3之后一个重要特征是反射(reflection),它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。

ApplicationContext context = new FileSystemXmlApplicationContext(  "applicationContext.xml");   

A a = (A) context.getBean("a"); 

pojo类的属性也是可以通过Spring注入进去的。Spirng不但可以注入基本类型,而且可以注入像List,Map这样的类型。

Map类型的配置:

技术分享
 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>  
View Code
<bean id="userAction" class="com.dobestself.action.UserAction"
scope="prototype">
<property name="userBO" ref="userBO" /> 论property可以传递的类型,如果把ref换成value则直接传递字符串(值),如果传递另外的bean,则要用ref。如果传递Map,参考上文。
</bean>


Spring运行机制剖析:
技术分享
  1 //定义一个Bean类,这个类用于存放一个Bean拥有的属性。
  2 /* Bean Id */  
  3     private String id;   
  4     /* Bean Class */  
  5     private String type;   
  6     /* Bean Property */  
  7  private Map<String, Object> properties = new HashMap<String, Object>();  
  8 /*接下来Spring 就开始加载我们的配置文件了,将我们配置的信息保存在一个HashMap中,HashMap的key就是Bean 的 Id ,HasMap 的value是这个Bean,只有这样我们才能通过context.getBean("animal")这个方法获得Animal这个类。我们都知道Spirng可以注入基本类型,而且可以注入像List,Map这样的类型,接下来就让我们以Map为例看看Spring是怎么保存的吧*/
  9 //Map配置可以像下面的
 10 <bean id="test" class="Test">   
 11         <property name="testMap">   
 12             <map>   
 13                 <entry key="a">   
 14                     <value>1</value>   
 15                 </entry>   
 16                 <entry key="b">   
 17                     <value>2</value>   
 18                 </entry>   
 19             </map>   
 20         </property>   
 21     </bean>  
 22 //Spring是怎样保存上面的配置
 23 if (beanProperty.element("map") != null) {   
 24                     Map<String, Object> propertiesMap = new HashMap<String, Object>();   
 25                     Element propertiesListMap = (Element) beanProperty   
 26                             .elements().get(0);   
 27                     Iterator<?> propertiesIterator = propertiesListMap   
 28                             .elements().iterator();   
 29                     while (propertiesIterator.hasNext()) {   
 30                         Element vet = (Element) propertiesIterator.next();   
 31                         if (vet.getName().equals("entry")) {   
 32                             String key = vet.attributeValue("key");   
 33                             Iterator<?> valuesIterator = vet.elements()   
 34                                     .iterator();   
 35                             while (valuesIterator.hasNext()) {   
 36                                 Element value = (Element) valuesIterator.next();   
 37                                 if (value.getName().equals("value")) {   
 38                                     propertiesMap.put(key, value.getText());   
 39                                 }   
 40                                 if (value.getName().equals("ref")) {   
 41                                     propertiesMap.put(key, new String[] { value   
 42                                             .attributeValue("bean") });   
 43                                 }   
 44                             }   
 45                         }   
 46                     }   
 47                     bean.getProperties().put(name, propertiesMap);   
 48                 }  
 49 /*接下来就进入最核心部分了,让我们看看Spring 到底是怎么依赖注入的吧,其实依赖注入的思想也很简单,它是通过反射机制实现的,在实例化一个类时,它通过反射调用类中set方法将事先保存在HashMap中的类属性注入到类中。让我们看看具体它是怎么做的吧。 
 50 首先实例化一个类,像这样 */
 51 public static Object newInstance(String className) {   
 52         Class<?> cls = null;   
 53         Object obj = null;   
 54         try {   
 55             cls = Class.forName(className);   
 56             obj = cls.newInstance();   
 57         } catch (ClassNotFoundException e) {   
 58             throw new RuntimeException(e);   
 59         } catch (InstantiationException e) {   
 60             throw new RuntimeException(e);   
 61         } catch (IllegalAccessException e) {   
 62             throw new RuntimeException(e);   
 63         }   
 64         return obj;   
 65     }  
 66 //接着它将这个类的依赖注入进去,像这样
 67 public static void setProperty(Object obj, String name, String value) {   
 68         Class<? extends Object> clazz = obj.getClass();   
 69         try {   
 70             String methodName = returnSetMthodName(name);   
 71             Method[] ms = clazz.getMethods();   
 72             for (Method m : ms) {   
 73                 if (m.getName().equals(methodName)) {   
 74                     if (m.getParameterTypes().length == 1) {   
 75                         Class<?> clazzParameterType = m.getParameterTypes()[0];   
 76                         setFieldValue(clazzParameterType.getName(), value, m,   
 77                                 obj);   
 78                         break;   
 79                     }   
 80                 }   
 81             }   
 82         } catch (SecurityException e) {   
 83             throw new RuntimeException(e);   
 84         } catch (IllegalArgumentException e) {   
 85             throw new RuntimeException(e);   
 86         } catch (IllegalAccessException e) {   
 87             throw new RuntimeException(e);   
 88         } catch (InvocationTargetException e) {   
 89             throw new RuntimeException(e);   
 90         }   
 91 }  
 92 /*最后它将这个类的实例返回给我们,我们就可以用了。我们还是以Map为例看看它是怎么做的,我写的代码里面是创建一个HashMap并把该HashMap注入到需要注入的类中,像这样,*/
 93 if (value instanceof Map) {   
 94                 Iterator<?> entryIterator = ((Map<?, ?>) value).entrySet()   
 95                         .iterator();   
 96                 Map<String, Object> map = new HashMap<String, Object>();   
 97                 while (entryIterator.hasNext()) {   
 98                     Entry<?, ?> entryMap = (Entry<?, ?>) entryIterator.next();   
 99                     if (entryMap.getValue() instanceof String[]) {   
100                         map.put((String) entryMap.getKey(),   
101                                 getBean(((String[]) entryMap.getValue())[0]));   
102                     }   
103                 }   
104                 BeanProcesser.setProperty(obj, property, map);   
105             }  
View Code

 

反射:由对象反推类

技术分享
 1 public static void printMethods(Class cl)
 2 {
 3 Method[] methods =cl.getDeclaredMethods();//返回一个包含方法对象的数组
 4 for(Method m : methods)//循环该类的每个方法
 5 {
 6 Class retType = m.getReturnType();//该方法的返回类型,
 7 Sting name = m.getName();//获得方法名
 8 Systen.out.print(" "+Modifier.toString(m.getModifiers());打印方法修饰符
 9 System.out.print(" "+retType.getName() + " " + name +"(");
10 
11 Class[] paramTypes = m.getParameterTypes();//获得一个方法参数数组(getparameterTypes用于返回一个描述参数类型的Class对象数组)
12 
13 for(int j = 0 ; j < paramTypes.length ; j++)
14 
15 {
16 if ( j > 0 ) System.out.print(" , ");   //如果有多个参数,中间则用逗号隔开,否则直接打印参数
17 System.out.print (paramTypes[ j ].getName);
18 }
19 System.out.println (" );");
20 }} 
21 
22 //////////getparameterTypes方法用于返回一个描述参数类型的Class对象数组)
View Code

 

 

参考文献:

http://blog.csdn.net/it_man/article/details/4402245

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。