欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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