此时心情:有时候工作的很努力,很认真也会被辞退,被小外包公司请辞,当然也是一个重新认识自己,提高自己的机会
我对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 源码过于庞大了,无从下手,以菜鸟的心面的世界,不管我写什么,都是在自己的世界重复发明轮子而已。