首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

模拟spring @Resource形式的依赖注入

2012-10-11 
模拟spring @Resource方式的依赖注入.??package org.cgz.test import java.beans.Introspectorimport ja

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

?

?

package org.cgz.test;&nbsp;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;&nbsp;import org.apache.commons.beanutils.ConvertUtils;import org.dom4j.Document;import org.dom4j.Element;import org.dom4j.XPath;import org.dom4j.io.SAXReader;&nbsp;public class MyClassPathXmlApplicationContext {&nbsp;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);}}

热点排行