自己对spring ioc的理解
程序员文章站
2022-07-14 10:35:09
...
此时心情:有时候工作的很努力,很认真也会被辞退,被小外包公司请辞,当然也是一个重新认识自己,提高自己的机会
我对spring ioc的理解是,1解析xml2利用反射生成类3利用反射构建类之间注入关系
1.解析xml
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="room" class="com.howto.parseXML.model.Room"> <property name="person" ref="person" /> </bean> <bean id="person" class="com.howto.parseXML.model.Person"> </bean> </beans>
package com.howto.parseXML.util; import java.io.File; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; public class ParseXML { static Logger logger = Logger.getLogger(ParseXML.class.getName()); public Map<String, Map<String, Object>> parseIOC(String filename) { List parseList = new ArrayList(); SAXReader saxReader = new SAXReader(); Document document; Map<String, Map<String, Object>> iocMap = new HashMap<String, Map<String, Object>>(); try{ InputStream input = this.getClass().getClassLoader().getResourceAsStream(filename); document = saxReader.read(input); //document = saxReader.read(new File(filename)); Element root_EL = document.getRootElement(); for(Iterator iter=root_EL.elementIterator();iter.hasNext();) { Element bean_EL = (Element)iter.next(); Map<String, Object> tempMap = new HashMap<String, Object>(); tempMap.put("id", bean_EL.attribute("id").getValue()); tempMap.put("class", bean_EL.attribute("class").getValue()); List<Map<String, String>> propertyList = new ArrayList<Map<String, String>>(); for(Iterator iter0=bean_EL.elementIterator();iter0.hasNext();){ Element property_EL = (Element)iter0.next(); Map<String, String> propertyMap = new HashMap<String, String>(); propertyMap.put("name", property_EL.attribute("name").getValue()); propertyMap.put("ref", property_EL.attribute("ref").getValue()); propertyList.add(propertyMap); } tempMap.put("property", propertyList); iocMap.put(bean_EL.attribute("id").getValue(), tempMap); } } catch(DocumentException e) { e.printStackTrace(); } return iocMap; } }
2and3反射生成类并存入map中,构建注入关系
package com.howto.ioc; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import com.howto.parseXML.util.ParseXML; public class BeanFactory { public static Map<String, Object> beanContainer = new HashMap<String, Object>(); public static void init() { //通过 反射 初始化 bean instanceBean(); //构建 bean 依赖关系 invokeBean(); System.out.println("init success!"); } public static ParseXML parseXML = new ParseXML(); //解析 xml public static Map<String, Map<String, Object>> beanXML = parseXML.parseIOC("application.xml"); private static void instanceBean() { Set<String> beanKeys = beanXML.keySet(); //初始化 bean for(String beanID: beanKeys) { Map<String, Object> beanDesc = beanXML.get(beanID); Object bean = getBean(beanID); beanContainer.put(beanID, bean); } } private static void invokeBean() { Set<String> beanKeys = beanXML.keySet(); for(String beanID: beanKeys) { Map<String, Object> beanDesc = beanXML.get(beanID); invoke(beanDesc); } } private static void invoke(Map<String, Object> beanDesc) { Class<?> beanClass; try { beanClass = Class.forName((String)beanDesc.get("class")); List<Map<String, Object>> methodList = getBeanSetMethod(beanClass, (List<Map<String, String>>)beanDesc.get("property")); for(Map<String, Object> tempMap: methodList) { Method setMethod = (Method)tempMap.get("method"); Class<?>[] para = (Class<?>[])tempMap.get("para"); String beanID = (String)beanDesc.get("id"); Object obj = getBean(beanID); setMethod.invoke(obj, tempMap.get("ref")); System.out.println(obj); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } private static List<Map<String, Object>> getBeanSetMethod(Class<?> beanClass, List<Map<String, String>> propertylist) { List<Map<String, Object>> setMethodList = new ArrayList<Map<String, Object>>(); for(Map<String, String> propertyMap: propertylist) { Map<String, Object> tempMap = new HashMap<String, Object>(); Method setProMethod = getSetMethod(beanClass, propertyMap); Class<?> para[] = setProMethod.getParameterTypes(); tempMap.put("methodName", setProMethod.getName()); tempMap.put("para", para); tempMap.put("method", setProMethod); tempMap.put("ref", getBean(propertyMap.get("ref"))); setMethodList.add(tempMap); } return setMethodList; } //拿到 属性set 方法method private static Method getSetMethod(Class<?> beanClass, Map<String, String> propertyMap) { Method[] methods = beanClass.getMethods(); for(Method tempMethod: methods) { if(tempMethod.getName().equals(getSetPramMethodName(propertyMap))) return tempMethod; } return null; } //生成 属性 set 方法名 private static Object getSetPramMethodName(Map<String, String> propertyMap) { String prameterName = propertyMap.get("name"); String setPramMethodName = "set" + prameterName.substring(0, 1).toUpperCase() + prameterName.substring(1); return setPramMethodName; } private static Object getBean(String beanID) { if(beanContainer.containsKey(beanID)) { return beanContainer.get(beanID); } else { Map<String, Object> beanDesc = beanXML.get(beanID); Object obj = null; try { obj = Class.forName((String)beanDesc.get("class")).newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return obj; } } }
4将其加入到web中,通过servletcontextlistener
package com.howto.ioc; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class IocServletContextListener implements ServletContextListener { @Override public void contextDestroyed(ServletContextEvent arg0) { } @Override public void contextInitialized(ServletContextEvent arg0) { BeanFactory.init(); } }
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>ioc_v0.1</display-name> <listener> <listener-class>com.howto.ioc.IocServletContextListener</listener-class> </listener> </web-app>
注:其中model类
package com.howto.parseXML.model; public class Room { public String roomName; public Person person; public String getRoomName() { return roomName; } public void setRoomName(String roomName) { this.roomName = roomName; } public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } }
package com.howto.parseXML.model; public class Person { public String personName; public String age; public String getAge() { return age; } public void setAge(String age) { this.age = age; } public String getPersonName() { return personName; } public void setPersonName(String personName) { this.personName = personName; } }
之前一直认为ioc很神秘,当真正去了解它的时候,才发现,其思想并不复杂,只是spring 源码过于庞大了,无从下手,以菜鸟的心面的世界,不管我写什么,都是在自己的世界重复发明*而已。
上一篇: Spring线程池开发实战
下一篇: yznxing 的动态