用java的spring实现一个简单的IOC容器示例代码
要想深入的理解IOC的技术原理,没有什么能比的上我们自己实现它。这次我们一起实现一个简单IOC容器。让大家更容易理解SpringIOC的基本原理。
这里会涉及到一些java反射的知识,如果有不了解的,可以自己去找些资料看看。
注意
在上一篇文章,我说,启动IOC容器时,Spring会将xml文件里面配置的bean扫描并实例化,其实这种说法不太准确,所以我在这里更正一下,xml文件里面配置的非单利模式的bean,会在第一次调用的时候被初始化,而不是启动容器的时候初始化。但是我们这次要做的例子是容器启动的时候就将bean初始化。特此说明一下,害怕误导初学者。
现在我们开始做一个简单的IOC容器
思路:
1,启动容器时,加载xml文件。
2,读取xml文件内的bean信息,并使用反射技术将bean实例化,并装入容器。
3,确认bean之间的以来关系,进行注入。
下面直接上代码,先看配置文件,与上一篇文章中使用的例子是一样的,我们这次继续使用上一篇文章的吃苹果和吃橘子的例子,只不过这次我们用我们自己写的IOC容器,所以,我只粘贴了关键代码。
此处为关键代码
packageit.spring.liao.com; importjava.io.InputStream; importjava.lang.reflect.Method; importjava.util.HashMap; importjava.util.Iterator; importjava.util.Map; importorg.dom4j.Attribute; importorg.dom4j.Document; importorg.dom4j.Element; importorg.dom4j.io.SAXReader; publicclassBeanFactory{ //用于存放bean实例的集合 privateMapbeanMap=newHashMap (); /** *bean工厂的初始化.
* *@paramxml *配置文件路径 */ publicvoidinit(Stringxml){ try{ //1.创建读取配置文件的reader对象 SAXReaderreader=newSAXReader(); //2.获取当前线程中的类装载器对象 ClassLoaderclassLoader=Thread.currentThread().getContextClassLoader(); //3.从class目录下获取指定的xml文件 InputStreamins=classLoader.getResourceAsStream(xml); //4.使用dom4j解析xml文件 Documentdoc=reader.read(ins); Elementroot=doc.getRootElement(); //5.初始化bean setBean(root); //6.注入bean的依赖关系 setPv(root); }catch(Exceptione){ System.out.println(e.toString()); } } /** *初始化bean * *@paramroot *xml文件 *@throwsException */ publicvoidsetBean(Elementroot)throwsException{ //1.遍历xml文件当中的Bean实例 for(Iteratori=root.elementIterator("bean");i.hasNext();){ Elementfoo=(Element)i.next(); //2.针对每个Bean实例,获取bean的属性id和class Stringid=foo.attribute("id").getText(); Stringcls=foo.attribute("class").getText(); //3.利用Java反射机制,通过class的名称获取Class对象 Classbean=Class.forName(cls); //4.创建对象 Objectobj=bean.newInstance(); //5.将对象放入beanMap中,其中key为bean的id值,value为bean的实例 beanMap.put(id,obj); } } /** *注入bean的依赖关系 * *@paramroot *xml文件 *@throwsException */ publicvoidsetPv(Elementroot)throwsException{ for(Iteratorit=root.elementIterator("bean");it.hasNext();){ Elementfoo=(Element)it.next(); //1.针对每个Bean实例,获取bean的属性id和class Stringcls=foo.attribute("class").getText(); Stringid=foo.attribute("id").getText(); //2.利用Java反射机制,通过class的名称获取Class对象 Classbean1=Class.forName(cls); //3.获取对应class的信息 java.beans.BeanInfoinfo=java.beans.Introspector.getBeanInfo(bean1); //4.获取其属性描述 java.beans.PropertyDescriptorpd[]=info.getPropertyDescriptors(); //5遍历该bean的property属性 for(Iteratorite=foo.elementIterator("property");ite.hasNext();){ Elementfoo2=(Element)ite.next(); //6.获取该property的name属性 Stringname=foo2.attribute("name").getText(); Stringref=foo2.attribute("ref").getText(); //7.在类中寻找与xml配置文件中该bean的property属性名相同的属性 for(intk=0;k详细的解释都在代码的注释中,这个例子可以帮助你更深刻的理解spring的基本技术原理。但Spring的复杂程度远远高于这个例子,再说一次,springIOC中使用懒加载机制,在启动springIOC时,只会实例化单例模式的bean,不会实例化普通的bean,关于单例模式还是其他模式,是可以自己配置的,我们会在后面的文章中讲解,非单例模式bean的实例化,发生在第一次调用的时候,与我们这个例子不太一样。这个例子只供了解SpringIOC的基本原理,真实情况要复杂的多,需要我们一点点的去学习,不积跬步无以至千里。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。