IOC在java框架中到处可见,我们只需要创建类,而不需要自己来创建实例,以及实例及实例之间的组织关系,而是通过配置文件或者注解来表明对象与对象之间的关系,最终有第三方根据配置文件及注解将需要的组件对象进行实例化的过程就是IOC。不知道这个理解是否正确,就将就着这么理解吧。通常我们使用别的框架来完成这个步骤。spring 大概大家都知道,典型的IOC ,实现也很强大。不过,spring 还是java写的,自己也来搞一个吧,虽然简单,但也能说明问题;即使很烂,也是一种实现。对吧?如果你是大牛,注意:别笑掉大牙!
接下来就自己完成这么一个小框架吧!首先声明,所有的IOC 在本人看来必须要使用java 的反射技术,如果没有反射技术,那么这一切都是空话。 废话不说 开始吧!
首先我们定义一个类似spring配置文件的xml,用来定义需要框架组织的对象及组织关系。
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="dao" class="com.sample.spring.egclasses.EgDao" single="true"/> <bean id="service" class="com.sample.spring.egclasses.EgSevice"> <setProperty name="egDao" refer="dao"/> </bean> <bean id="service1" class="com.sample.spring.egclasses.EgSevice"> <setProperty name="egDao" refer="dao"/> </bean> </beans>
看看这2个配置的类
package com.sample.spring.egclasses; public class EgDao { public void callMe() { System.out.println("Dao is called"); } }
package com.sample.spring.egclasses; public class EgSevice { private EgDao egDao; public void callMe(){ egDao.callMe(); } public EgDao getEgDao() { return egDao; } }
接下来编写一个了一个classloader 本来想在这个里面干点什么,但是现在还没有想到。
package com.sample.spring; public class SampleClassLoader extends ClassLoader { private SampleClassLoader() { super(); } private static final SampleClassLoader thisInstance; static{ thisInstance=new SampleClassLoader(); } public static SampleClassLoader getClassLoader(){ return thisInstance; } }
接下来就是我们这雷人的框架核心了。
package com.sample.spring; import java.io.IOException; import java.lang.reflect.Field; import java.util.HashMap; import java.util.List; import java.util.Map; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.JDOMException; import org.jdom2.input.SAXBuilder; public class SampleSpringContainer { private static final Map<String,Bean> beans=new HashMap<String, Bean>(); static final Map<String,Object> singles=new HashMap<String, Object>(); static{ SAXBuilder sb = new SAXBuilder(); try { Document doc =sb.build(SampleSpringContainer.class.getClassLoader().getResourceAsStream("com/sample/spring/springSample.xml")); Element rootElement = doc.getRootElement(); List<Element> beans = rootElement.getChildren("bean"); buidBeans(beans); initBeans(); } catch (JDOMException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private static void buidBeans(List<Element> beans){ for(Element bean :beans){ String id = bean.getAttributeValue("id"); if(SampleSpringContainer.beans.containsKey(id))continue; String clas = bean.getAttributeValue("class"); boolean single =Boolean.valueOf(bean.getAttributeValue("single")); Bean mbean=new Bean(clas, single); SampleSpringContainer.beans.put(id, mbean); List<Element> dependences = bean.getChildren("setProperty"); for(Element dependence :dependences){ String name = dependence.getAttributeValue("name"); String agr = dependence.getAttributeValue("refer"); Bean dbean2 = SampleSpringContainer.beans.get(agr); if(dbean2==null){ buidDependenceBeans(beans,agr); dbean2=SampleSpringContainer.beans.get(agr); } if(dbean2==null){ throw new IllegalArgumentException(id+"property "+name+"is not found"); } mbean.getDependence().put(name, dbean2); } } } private static void initBeans() { for(Map.Entry<String, Bean> bean:beans.entrySet()){ if(!bean.getValue().getDependence().isEmpty()){ for(Map.Entry<String, Bean> dep:bean.getValue().getDependence().entrySet()){ deepBuildDependence(dep.getValue().getDependence()); } } singles.put(bean.getValue().getClassName(), bean.getValue().newInstance()); } } private static void deepBuildDependence(Map<String, Bean> dependence) { for(Map.Entry<String, Bean> dep:dependence.entrySet()){ Bean bean = dep.getValue(); if(!bean.getDependence().isEmpty()){ deepBuildDependence(bean.getDependence()); } singles.put(bean.getClassName(), bean.newInstance()); } } private static void buidDependenceBeans(List<Element> beans,final String rid){ for(Element bean :beans){ String id = bean.getAttributeValue("id"); if(!rid.equals(id))continue; String clas = bean.getAttributeValue("class"); boolean single =Boolean.valueOf(bean.getAttributeValue("single")); Bean mbean=new Bean(clas, single); SampleSpringContainer.beans.put(id, mbean); List<Element> dependences = bean.getChildren("setProperty"); for(Element dependence :dependences){ String name = dependence.getAttributeValue("name"); String agr = dependence.getAttributeValue("refer"); Bean dbean2 = SampleSpringContainer.beans.get(agr); if(dbean2==null){ buidDependenceBeans(beans,agr); dbean2=SampleSpringContainer.beans.get(agr); } if(dbean2==null){ throw new IllegalArgumentException(""); } mbean.getDependence().put(name, dbean2); } } } public static Object getBean(final String beanId){ Bean bean = beans.get(beanId); if(bean!=null){ if(bean.isSingle()){ return singles.get(beanId); }else{ return bean.newInstance(); } } return null; } } class Bean{ private String className; private boolean isSingle; public Bean(String className, boolean isSingle) { super(); this.className = className; this.isSingle = isSingle; } private Map<String,Bean> dependence=new HashMap<String, Bean>(); public String getClassName() { return className; } public void setClassName(String className) { this.className = className; } public boolean isSingle() { return isSingle; } public Map<String, Bean> getDependence() { return dependence; } public Object newInstance(){ SampleClassLoader classLoader = SampleClassLoader.getClassLoader(); Object newInstance=null; try { Class<?> loadClass = classLoader.loadClass(className); newInstance= loadClass.newInstance(); for(Map.Entry<String, Bean> entity:dependence.entrySet()){ Field field = loadClass.getDeclaredField(entity.getKey()); field.setAccessible(true); if(entity.getValue().isSingle()){ field.set(newInstance,SampleSpringContainer.singles.get(entity.getValue().getClassName())); }else{ field.set(newInstance, entity.getValue().newInstance()); } } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } return newInstance; } }
这个类有点长,此处并没有太多的考虑,最靠谱的首先是能够实现,对吧?
呵呵 在编写一个带main函数的类测试一下,总的有图有真相吧?
package com.sample.spring; import com.sample.spring.egclasses.EgSevice; public class TestSpring { /** * @param args */ public static void main(String[] args) { EgSevice bean = (EgSevice) SampleSpringContainer.getBean("service"); bean.callMe(); EgSevice bean1 = (EgSevice) SampleSpringContainer.getBean("service1"); bean1.callMe(); System.out.println(bean.getEgDao()==bean1.getEgDao()); } }
执行结果如图:
没有骗你吧?不管咋地 首先是完成了功能。 呵呵 注解篇,请看续集!
相关推荐
springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC...
自己动手做框架——ORM,MVC,IOC框架及整合视频教程 源码
根据Spring的IoC原理,实现自己的IoC框架。
IOC框架详解,很好的IOC的参考资料,相信介绍了IOC框架
对多种IOC框架进行比较,对各自的优缺点进行描述
spring_ioc框架学习文档
Android进阶——框架打造之IOC框架 实现通过Id找到控件的功能 实现通过Id找到Color、String资源 实现绑定view的点击事件、长按事件 实现绑定SetContentView 实现绑定网络的检测功能
C#实现的IOC和AOP框架,供学习
自己做的一个小型的IOC框架,希望大家一起研究下
1、Flex IOC 框架概览PDF完整版 2、Flex IOC 框架概览配套源码 3、IoC容器和Dependency Injection模式中文版
Spring框架系列(7) - Spring IOC实现原理详解之IOC初始化流程.doc
自己写了三个分别关于WEB,IOC,ORM的框架现将全部开源,内有说明文档,测试示例项目,框架源代码文件,sql语句等
轻量级的IOC框架,用于取代Spring在j2se项目中进行使用。
《仿 Spring 手写 IoC、AOP 框架》博客附件。 博客地址:https://blog.csdn.net/Supreme_Sir/article/details/109100886
简单的ioc框架, just a simple
利用Castle框架中IOC技术的技术文档
Spring框架中的ioc的幽默解释
Spring框架-IoC实现CRUD
手写spring框架ioc+aop+mvc
spring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demo...