`
xudongcsharp
  • 浏览: 468954 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

模拟Spring控制反转、依赖注入(包注解)

 
阅读更多
package com.spring.test;

import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
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;


public class MySpring {

	List<BeanDefinition> beanDefines=new ArrayList<BeanDefinition>();
	Map<String, Object> map=new HashMap<String, Object>();
	
	public MySpring(String filename){
		//读取XML文件,遍历bean,存放到List
		readXML(filename);
		//遍历bean集合,利用反射实例化bean,存放到Map
		instanceBean();
		//依赖注入
		injectObject();
		//注解注入
		annotationInject();
	}

	private void annotationInject() {
		for(String name : map.keySet()){
			Object bean=map.get(name);
			if(bean!=null){
				try {
					PropertyDescriptor[] ps=Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
					for(PropertyDescriptor propertyDescriptor : ps){
						Method setter=propertyDescriptor.getWriteMethod();//获取setter方法
						
						//判断注解是否存在
						if(setter!=null && setter.isAnnotationPresent(MyResource.class)){
							MyResource myResource=setter.getAnnotation(MyResource.class);
							Object value=null;
							//声明name属性
							if(myResource.name()!=null && !"".equals(myResource.name())){
								value=map.get(myResource.name());
							}else{
								value=map.get(propertyDescriptor.getName());
								if(value==null){
									for(String key : map.keySet()){
										if(propertyDescriptor.getPropertyType().isAssignableFrom(map.get(key).getClass())){
											value=map.get(key);
											break;
										}
									}
								}
							}
							setter.setAccessible(true);
							setter.invoke(bean, value);//把引用对象注入到属性中
						}
					}
					//字段
					Field[] fields=bean.getClass().getFields();
					for(Field field : fields){
						if(field.isAnnotationPresent(MyResource.class)){
							MyResource myResource=field.getAnnotation(MyResource.class);
							Object value=null;
							//声明name属性
							if(myResource.name()!=null && !"".equals(myResource.name())){
								value=map.get(myResource.name());
							}else{
								value=map.get(field.getName());
								if(value==null){
									for(String key : map.keySet()){
										if(field.getType().isAssignableFrom(map.get(key).getClass())){
											value=map.get(key);
											break;
										}
									}
								}
							}
							field.setAccessible(true);
							field.set(bean,value);
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	private void injectObject() {
		//循环所有的bean节点
		for(BeanDefinition beanDefinition : beanDefines){
			Object bean= map.get(beanDefinition.getId());
			if(bean!=null){
				
				try {
					PropertyDescriptor[] ps=Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
					//循环所有的property节点
					for(PropertyDefinition propertyDefinition : beanDefinition.getProperties()){
						for(PropertyDescriptor propertyDescriptor : ps){
							if(propertyDefinition.getName().equals(propertyDescriptor.getName())){
								Method setter=propertyDescriptor.getWriteMethod();//获取setter方法
								if(setter!=null){
									Object value=map.get(propertyDefinition.getRef());
									//如果private,设置允许访问
									setter.setAccessible(true);
									setter.invoke(bean, value);//把引用对象注入到属性中
								}
								break;
							}
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	@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");//创建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");//创建beans/property查询路径
            propertysub.setNamespaceURIs(nsMap);//设置命名空间
            List<Element> propertys = propertysub.selectNodes(element);//获取文档下所有property节点 
            for(Element property : propertys){
            	String propertyName=property.attributeValue("name");
            	String propertyRef=property.attributeValue("ref");
            	System.out.println(propertyName+propertyRef);
            	PropertyDefinition pd=new PropertyDefinition(propertyName,propertyRef);
            	beanDefine.getProperties().add(pd);
            }
            
            beanDefines.add(beanDefine);
         }   
        }catch(Exception e){   
            e.printStackTrace();
        }
	}
	
	private void instanceBean() {
		for(BeanDefinition bean : beanDefines){
			try {
				if(bean.getClassName()!=null && !"".equals(bean.getClassName()))
					//实例化Bean对象
					map.put(bean.getId(), Class.forName(bean.getClassName()).newInstance());
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	public Object getBean(String id){
		return this.map.get(id);
	}
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics