`
xiang37
  • 浏览: 414262 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Spring源码学习之二

阅读更多

本次主要记录一下spring中的依赖注入。

 

先来段代码,

package com.xiva.mySpring;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;

import com.xiva.bean.MyBean;
import com.xiva.bean.PropertyDefinition;

/**
 * 
 * @author XIVA
 * @Description 简化的Spring容器
 */
public class XivaContext extends XivaAbsAppContext{

	private List<MyBean> beanList = new ArrayList<MyBean>();
	
	private Map<String, Object> sigletons = new HashMap<String, Object>();
	
	private Map<String, PropertyDefinition> property = new HashMap<String, PropertyDefinition>();
	
	
	public XivaContext(String xmlPath){
		this.readXML(xmlPath);
		this.instanceBean();
		this.injectBean();
	}
	
	private void injectBean() {
		// TODO Auto-generated method stub
		for(Map.Entry<String, PropertyDefinition> map :property.entrySet()){
			String key = map.getKey();
			PropertyDefinition value = map.getValue();
			
			Object object = sigletons.get(key);
			Object injectObject  = sigletons.get(value.getRef());
			Class<?> clazz = object.getClass();
			try{
				String methodName = "set" + firToUpper(value.getRef());
				Method setMethod = clazz.getMethod(methodName, injectObject.getClass().getInterfaces());
				setMethod.invoke(object, injectObject);
			}catch(Exception e){
				e.printStackTrace();
			}
		}
		
	}

	/**
	 * @Description 解析spring配置文件,初始化bean;其中对bean中配置的property
	 * @author XIVA
	 * @param fileName
	 */
	@SuppressWarnings("unchecked")
	private void readXML(String fileName){
		SAXReader saxReader = new SAXReader();
		Document document = null;
		try{
			URL xmlPath = this.getClass().getClassLoader().getResource(fileName);
			document = saxReader.read(xmlPath);
			Map<String, String> nsMap = new HashMap<String, String>();
			nsMap.put("ns", "http://www.springframework.org/schema/beans");//加入命名空间
			XPath xsub = document.createXPath("//ns:beans/ns:bean");//
			xsub.setNamespaceURIs(nsMap);//设置命名空间
			List<Element> beans = xsub.selectNodes(document);//获取节点
			MyBean bean = null;
			for (Element element:beans){
				String id = element.attributeValue("id");
				String clazz = element.attributeValue("class");
				if (id!=null && clazz!=null){
					bean = new MyBean(id, clazz);
					beanList.add(bean);
				}
				List<Element> pList = element.elements("property");
				if (pList != null && pList.size() > 0){
					PropertyDefinition propDef = null;
					for (Element pEle:pList){
						String name = pEle.attributeValue("name");
						String ref = pEle.attributeValue("ref");
						if (name!=null && ref!=null){
							propDef = new PropertyDefinition(name,ref);
							property.put(id, propDef);
						}
					}
				}
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	/**
	 * 
	 * @Description 实例化bean
	 * @author XIVA
	 */
	private void instanceBean(){
		Object object = null;
		for(MyBean bean:beanList){
			try{
				String clazzStr = bean.getBeanClass();
				Class<?> clazz = Class.forName(clazzStr);
				for(Constructor<?> con:clazz.getDeclaredConstructors()){
					con.setAccessible(true);
				}
				object = clazz.newInstance();
				sigletons.put(bean.getBeanId(), object);
			}catch(Exception e){
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 获取Bean实例
	 */
	@Override
	public Object getBean(String beanName) {
		// TODO Auto-generated method stub
		return sigletons.get(beanName);
	}
	
	/**
	 * 首字母大写
	 * @param field
	 * @return
	 */
	private static String firToUpper(String field){
		
		String firStr = field.substring(0, 1);
		firStr = firStr.toUpperCase();
		field = firStr + field.substring(1, field.length());
		return field;
	}

}

 依赖注入,对于Spring的实现有两种;第一种是在构造函数中,来注入外部的类的实例,第二种方式是通过set方法来实例化。当然有了JPA后了,我们又可以通过注解autoware来实现,但是这种原理都是一样的。都是通过类反射,然后找到相应的注解或者解析xml来实现。

	/**
	 * 
	 * @Description 注入
	 * @author XIVA
	 */
	private void injectBean() {
		// TODO Auto-generated method stub
		for (Map.Entry<String, PropertyDefinition> map :property.entrySet()){
			String key = map.getKey();
			PropertyDefinition value = map.getValue();
			
			Object object = sigletons.get(key);
			Object injectObject  = sigletons.get(value.getRef());
			Class<?> clazz = object.getClass();
			try{
				String methodName = "set" + firToUpper(value.getRef());
				Method setMethod = clazz.getMethod(methodName, injectObject.getClass().getInterfaces());
				setMethod.invoke(object, injectObject);
			}catch (Exception e){
				e.printStackTrace();
			}
		}	
	}

 上面方法就是通过反射来注入bean的。

 

List<Element> pList = element.elements("property");
				if (pList != null && pList.size() > 0){
					PropertyDefinition propDef = null;
					for (Element pEle:pList){
						String name = pEle.attributeValue("name");
						String ref = pEle.attributeValue("ref");
						if (name!=null && ref!=null){
							propDef = new PropertyDefinition(name,ref);
							property.put(id, propDef);
						}
					}
				}
 

这段代码是解析xml文件中property属性来放入

private Map<String, PropertyDefinition> property = new HashMap<String, PropertyDefinition>();

上面定义的map中。
<bean id="moduleService" class="com.xiva.module.service.impl.ModuleServiceImpl">
			<property name="moduleDao" ref="moduleDao"></property>
		</bean>
 上面的property就是注入。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics