`
cowboy_bebop
  • 浏览: 110406 次
  • 性别: Icon_minigender_1
  • 来自: 火星
社区版块
存档分类
最新评论

模拟spring @Resource方式的依赖注入.

阅读更多

 

 

package org.cgz.test;
 
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
import org.apache.commons.beanutils.ConvertUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;
 
public class MyClassPathXmlApplicationContext {
 
	private List<BeanDefinition> beanDefinitions = new ArrayList<BeanDefinition>();
	private Map<String, Object> intsances = new HashMap<String, Object>();
	/**
	* 容器初始化时 传入配置文件名称 读取配置文件..实例化bean
	* @param configFileName
	*/
	public MyClassPathXmlApplicationContext(String configFileName) {
		readConfig(configFileName);
		instanceBeans();
		annotationInject();
		Injected();
	}
&nbsp;
	/**
	* 注解实现依赖注入
	*/
	private void annotationInject() {
		/**
		* 遍历bean,获取bean里的所有属性描述对象,遍历属性描述对象数组.
		* ---获取属性的setter方法.如果该属性setter方法存在,判断方法上是否有MyResource注解,
		*     如果有,获取注解对象,通过注解对象获取name值
		*         如果name值存在:根据name值查找Map中是否有该名称的bean,如果有,调用该属性的setter方法执行注入.
		*         如果name值不存在:获取该属性的名称,从map中查找是否有此名称的bean.
		*                         如果有:调用setter方法注入
		*                         没有:获取该属性的类型,遍历map查找map中是否有和此属性类型一致的bean,如果有,则执行注入
		* 
		*---获取该属性,判断该属性上是否有MyResource注解
		*     如果有:获取该注解的对象,通过该对象获取name值
		*        如果name值存在:根据name值查找map中是否有该bean如果有则执行注入
		*        如果name值不存在:获取该属性的名称,查找map中是否有该名称的bean
		*                        如果有:执行注入
		*                        没有:获取该属性的类型 遍历map中判断是否有和该类型一致的bean
		* 
		*/
		for(String beanName : intsances.keySet()) {
			Object bean = intsances.get(beanName);
			if(bean != null) {
				try {
					PropertyDescriptor[] ps =  Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
					for(PropertyDescriptor propertyDesc : ps) {
						Method setter = propertyDesc.getWriteMethod();
						if(setter != null && setter.isAnnotationPresent(MyResource.class)) {
							MyResource myResource = setter.getAnnotation(MyResource.class);
							Object value = null;
							if(myResource.name() != null && !"".equals(myResource.name())) {
								value = intsances.get(myResource.name());
							}else {
								value = intsances.get(propertyDesc.getName());
								if(value == null) {
									for(String key : intsances.keySet()) {
										if(propertyDesc.getPropertyType().isAssignableFrom(intsances.get(key).getClass())) {
											value = intsances.get(key);
											break;
										}
									}
								}
							}
							setter.setAccessible(true);
							setter.invoke(bean, value);
						}
					
						Field[] fields = bean.getClass().getDeclaredFields();
						for(Field field : fields) {
							if(field.isAnnotationPresent(MyResource.class)) {
								MyResource myResource = field.getAnnotation(MyResource.class);
								Object value = null;
								if(myResource.name() != null && !"".equals(myResource.name())) {
									value = intsances.get(myResource.name());
								}else {
									value = intsances.get(field.getName());
									if(value == null) {
										for(String key : intsances.keySet()) {
											if(field.getType().isAssignableFrom(intsances.get(key).getClass())) {
												value = intsances.get(key);
												break;
											}
										}
									}
								}
								field.setAccessible(true);
								field.set(bean, value);
							}
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}
&nbsp;
	/**
	* 注入属性的值
	*/
	private void Injected() {
		for(BeanDefinition beanDefinition : beanDefinitions) {
			Object bean = intsances.get(beanDefinition.getId());
			if(bean != null) {
				try {
					//通过Java的内省机制获取到对象中所有属性的描述信息
					PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
					for(PropertyDefinition propertyDefinition : beanDefinition.getPropertys()) {
						for(PropertyDescriptor propertyDesc : ps) {
							//判断XML文件中解析出来的属性和对象中的属性名称是否一样
							if(propertyDefinition.getName().equals(propertyDesc.getName())) {
								//获取属性的setter方法
								Method setter = propertyDesc.getWriteMethod();
								if(setter != null) {
									Object value = null;
									//如果property中没有ref属性,那么表示后面将进行的是基本属性的装配
									if(propertyDefinition.getRef() != null && !"".equals(propertyDefinition.getRef().trim())) {
										value = intsances.get(propertyDefinition.getRef());
									}else {
										value = ConvertUtils.convert(propertyDefinition.getValue(), propertyDesc.getPropertyType());
									}
									setter.setAccessible(true);
									//调用对象的setter方法赋值
									setter.invoke(bean, value);
								}
								break;
							}
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}
&nbsp;
   /**
	* 通过反射获取bean的实例
	*/
	private void instanceBeans() {
		for(BeanDefinition beanDefinition : beanDefinitions) {
			try {
				if(beanDefinition.getClazz() != null && !"".equals(beanDefinition.getClazz())) {
					intsances.put(beanDefinition.getId(), Class.forName(beanDefinition.getClazz()).newInstance());
				}
			} catch (Exception e) {
				e.printStackTrace();
			} 
		}
	}
&nbsp;
	/**
	* 读取配置信息并将bean信息的描述对象存储到List中
	* @param configFileName
	*/
	@SuppressWarnings("unchecked")
	private void readConfig(String configFileName) {
		Document document=null; 
		Map<String,String> nsMap = new HashMap<String,String>();
		try{
			document = new SAXReader().read(this.getClass().getClassLoader().getResource(configFileName));
			nsMap.put("ns","http://www.springframework.org/schema/beans");    //加入命名空间
			XPath xsub = document.createXPath("//ns:beans/ns:bean");        //创建beans/bean查询路径
			xsub.setNamespaceURIs(nsMap);                                    //设置命名空间
			List<Element> beans = xsub.selectNodes(document);                //获取文档下所有bean节点 
			for(Element element: beans){
				String id = element.attributeValue("id");                    //获取id属性值
				String clazz = element.attributeValue("class");                //获取class属性值 
				BeanDefinition beanDefine = new BeanDefinition(id, clazz);
				XPath propertysub = element.createXPath("ns:property");        //设置命名空间
				propertysub.setNamespaceURIs(nsMap);
				List<Element> properties = propertysub.selectNodes(element);
				for(Element property : properties) {
					String propertyName = property.attributeValue("name");
					String propertyRef = property.attributeValue("ref");
					String propertyValue = property.attributeValue("value");
					PropertyDefinition propertyDefinition = new PropertyDefinition(propertyName, propertyRef,propertyValue);
					beanDefine.getPropertys().add(propertyDefinition);
				}
				beanDefinitions.add(beanDefine);
			} 
		}catch(Exception e){ 
			e.printStackTrace();
		}
	}
	/**
	* 外界获取bean对象的接口
	*/
	public Object getBean(String beanName) {
		return this.intsances.get(beanName);
	}
}
  • 大小: 69.3 KB
分享到:
评论
1 楼 laiweiweihi 2011-12-17  
这代码必须得重构哇,博主.

相关推荐

Global site tag (gtag.js) - Google Analytics