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>
<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 }
反射:由对象反推类
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对象数组)
参考文献:
http://blog.csdn.net/it_man/article/details/4402245
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。