自己对spring ioc的理解

此时心情:有时候工作的很努力,很认真也会被辞退,被小外包公司请辞,当然也是一个重新认识自己,提高自己的机会

我对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 源码过于庞大了,无从下手,以菜鸟的心面的世界,不管我写什么,都是在自己的世界重复发明轮子而已。

猜你喜欢

转载自mauersu.iteye.com/blog/1905634