java反射机制模拟Spring Ioc实现

88 篇文章 0 订阅
16 篇文章 0 订阅

 

                         java反射机制模拟Spring Ioc实现



前言


用Spring也有两年多时间了,一直以来都没时间深入研究它的内部实现机制。现在有时间开始研究Spring的Ioc,当然,说到Spring就让人想到Ioc和Aop了。本篇文章是利用java的反射机制模拟Ioc实现。


IoC理论的背景


在采用面向对象方法设计的软件系统中,底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑。即软件系统中对象之间的耦合,对象A和对象B之间有关联,对象B又和对象C有依赖关系,这样对象和对象之间有着复杂的依赖关系,所以才有了控制反转这个理论。


反射机制模拟Ioc


步骤:


第一步:定义服务的配置文件(指定服务名和服务路径)

<?xml version="1.0" encoding="utf-8" ?>   
<!-- DOCTYPE service - config SYSTEM " service.dtd " -->   
<beans>   
<!-- 用户服务 -->   
<bean name="UserService " class="com.ioc.service.UserService" template="normal" />   
<bean name="GnmkService" class="com.ioc.service.GoServiceImpl" template= "normal" />   
</beans> 

第二步:服务 初始化时将所有服务名和路径加载到一个静态的HashMap中

public class ServiceConfig {
	//启动服务时,需要将配置文件的信息读取放到serviceMap中。
	public static HashMap serviceMap = new HashMap();
	
	public static String getService(String serviceName) {
		serviceMap = (HashMap) prepareServiceMap();
		String serviceClass= "";
		serviceClass= ServiceConfig.serviceMap.get(serviceName).toString();  
		return serviceClass;
	}
	
	private static Map prepareServiceMap() {
		Map map = null;
		BeanFactory factory = new BeanFactory();
        try {
			map = factory.init("service.xml");
		} catch (Exception e) {
			e.printStackTrace();
		}
        return map;
	}
	
	public static void init(){
		BeanFactory factory = new BeanFactory();
		try {
			factory.init("service.xml");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}



第三步:定义一个service接口

public interface Service {
	public void execute();
}

第四步:服务实例化

public class ServiceExecuteHelper {
	public static void execute(String serviceName) {
		try {  
            //验证服务是否存在  
            String servicClass = ServiceConfig.getService(serviceName);  
            //如果服务存在就加载服务信息  
            if (servicClass != null && !servicClass.equals("")) {  
                 Class<?> classObject = Class.forName(servicClass);  
                 Service service = (Service) classObject.newInstance();  
                 service.execute();   
             } else{
            	 System.out.println("服务" + serviceName + "未定义");
             }
       }catch(Exception e) {  
    	   e.printStackTrace(); 
    	   System.out.println("服务" + serviceName + "不存在");
       }  
	}  

}

第五步:定义接口具体服务并实现接口类

public class GoServiceImpl implements Service{

	@Override
	public void execute() {
		System.out.println("执行的是GoServiceImpl");
	}

}

第六步:测试类

public class Test {
	public static void main(String[] args) {
		
		ServiceExecuteHelper.execute("UserService");
	}
}

第七步:提供装配服务的类

public class BeanFactory {
	private Map<String, Object> beanMap = new HashMap<String, Object>();
	
	/**
	 * 初始化配置文件.
	 * @param xml
	 * @throws Exception
	 */
	public Map init(String xml) throws Exception {
		//读取指定的配置文件
        SAXReader reader = new SAXReader();
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        //从class目录下获取指定的xml文件
        InputStream ins = classLoader.getResourceAsStream(xml);
        Document doc = reader.read(ins);
        Element root = doc.getRootElement();  
        Element foo;
        
        //遍历bean
        for (Iterator i = root.elementIterator("bean"); i.hasNext();) {  
               foo = (Element) i.next();
               //获取bean的属性id和class
               Attribute id = foo.attribute("id");  
               Attribute cls = foo.attribute("class");
               //利用Java反射机制,通过class的名称获取Class对象
               Class bean = Class.forName(cls.getText());
               //获取对应class的信息
               java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(bean);
               //获取其属性描述
               java.beans.PropertyDescriptor pd[] = info.getPropertyDescriptors();
               //设置值的方法
               Method mSet = null;
               //创建一个对象
               Object obj = bean.newInstance();
               //遍历该bean的property属性
               for (Iterator ite = foo.elementIterator("property"); ite.hasNext();) {  
                      Element foo2 = (Element) ite.next();
                      //获取该property的name属性
                      Attribute name = foo2.attribute("name");
                      String value = null;
                      //获取该property的子元素value的值
                      for(Iterator ite1 = foo2.elementIterator("value"); ite1.hasNext();) {
                             Element node = (Element) ite1.next();
                             value = node.getText();
                             break;

                      }
                     
                      for (int k = 0; k < pd.length; k++) {
                             if (pd[k].getName().equalsIgnoreCase(name.getText())) {
                                    mSet = pd[k].getWriteMethod();
                                    //利用Java的反射极致调用对象的某个set方法,并将值设置进去
                                    mSet.invoke(obj, value);
                             }
                      }
               }
               //将对象放入beanMap中,其中key为id值,value为对象
               beanMap.put(id.getText(), obj);
        }
        return beanMap;
	}
	
	/**
     * 通过bean的id获取bean的对象.
     * @param beanName bean的id
     * @return 返回对应对象
     */
     public Object getBean(String beanName) {
            Object obj = beanMap.get(beanName);
            return obj;
     }
}







  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值