要想深入的理解国际奥委会的技术原理,没有什么能比的上我们自己实现它。这次我们一起实现一个简单奥委会容器。让大家更容易理解Spring IOC的基本原理。
这里会涉及到一些java反射的知识,如果有不了解的,可以自己去找些资料看看。
<强>注意强>
在上一篇文章,我说,启动奥委会容器时,弹簧会将xml文件里面配置的bean扫描并实例化,其实这种说法不太准确,所以我在这里更正一下,xml文件里面配置的非单利模式的bean会在第一次调用的时候被初始化,而不是启动容器的时候初始化。但是我们这次要做的例子是容器启动的时候就将bean初始化。特此说明一下,害怕误导初学者。
现在我们开始做一个简单的国际奥委会容器
<>强思路:
强>
1,启动容器时,加载xml文件。
2,读取xml文件内的bean信息,并使用反射技术将bean实例化,并装入容器。
3,确认豆之间的以来关系,进行注入。
下面直接上代码,先看配置文件,与上一篇文章中使用的例子是一样的,我们这次继续使用上一篇文章的吃苹果和吃橘子的例子,只不过这次我们用我们自己写的奥委会容器,所以,我只粘贴了关键代码。
& lt; & # 63; xml version=" 1.0 " encoding=" utf - 8 " & # 63;比; & lt; !DOCTYPE BEAN公开”——//SPRING/DTD BEAN/EN” “http://www.springframework.org/dtd/spring-beans.dtd”在 & lt; beans> & lt; !——这是吃橘子的Bean——比; & lt; bean id=癳atOrange”类=癷t.spring.liao.com.EatOrange祝辞& lt;/bean> & lt; !——这是吃苹果的Bean——比; & lt; bean id=癳atApple”类=癷t.spring.liao.com.EatApple祝辞& lt;/bean> & lt; bean id=叭恕崩?癷t.spring.liao.com.Person”比; & lt; !——这里我们注入的是吃橘子的bean——比; & lt;属性名="吃" ref=" eatOrange "/比; & lt;/bean> & lt;/beans> >之前此处为关键代码
包it.spring.liao.com; 进口java.io.InputStream; 进口java.lang.reflect.Method; 进口java.util.HashMap; 进口java.util.Iterator; 进口java.util.Map; 进口org.dom4j.Attribute; 进口org.dom4j.Document; 进口org.dom4j.Element; 进口org.dom4j.io.SAXReader; 公开课BeanFactory {//用于存放豆实例的集合 私人Map<字符串,Object>beanMap=new HashMap<字符串,Object> ();/* * *豆工厂的初始化。& lt; br> * * @param xml *配置文件路径 */公共空间init (String xml) { 尝试{//1 .创建读取配置文件的读者对象 SAXReader读者=new SAXReader ();//2 .获取当前线程中的类装载器对象 类加载器类加载器=Thread.currentThread () .getContextClassLoader ();//3 .从类目录下获取指定的xml文件 InputStream ins=classLoader.getResourceAsStream (xml);//4。使用dom4j解析xml文件 文档doc=reader.read (ins); 根元素=doc.getRootElement ();//5 .初始化bean setBean(根);//6 .注入bean的依赖关系 setPv(根); }捕捉(异常e) { System.out.println (e.toString ()); } }/* * *初始化bean * * @param根 * xml文件 * @throws例外 */公共空间setBean(根元素){抛出异常//1 .遍历xml文件当中的Bean实例 迭代器(i=root.elementIterator (“bean”);i.hasNext ();) { 元素foo=(元素)i.next ();//2 .针对每个豆实例,获取Bean的属性id和类 字符串id=foo.attribute (" id ") .getText (); 字符串cls=foo.attribute(“阶级”).getText ();//3 .利用Java反射机制,通过类的名称获取类对象 类bean=forname (cls);//4 .创建对象 对象obj=bean.newInstance ();//5 .将对象放入beanMap中,其中主要为bean的id值,值为bean的实例 beanMap。把(id、obj); } }/* * *注入bean的依赖关系 * * @param根 * xml文件 * @throws例外 */公共空间setPv(根元素){抛出异常 (迭代器它=root.elementIterator (“bean”);it.hasNext ();) { 元素foo=(元素)it.next ();//1 .针对每个豆实例,获取Bean的属性id和类 字符串cls=foo.attribute(“阶级”).getText (); 字符串id=foo.attribute (" id ") .getText ();//2 .利用Java反射机制,通过类的名称获取类对象 类bean1=forname (cls);//3 .获取对应的类的信息 java.beans。BeanInfo信息=java.beans.Introspector.getBeanInfo (bean1);//4 .获取其属性描述 java.beans。PropertyDescriptor pd []=info.getPropertyDescriptors ();//5遍历该bean的属性属性 迭代器(尽管=foo.elementIterator(“财产”);ite.hasNext ();) { 元素foo2=(元素)ite.next ();//6 .获取该属性的名称属性 字符串名称=foo2.attribute(“名字”).getText (); 字符串ref=foo2.attribute (ref) .getText ();//7 .在类中寻找与xml配置文件中该bean的属性属性名相同的属性 for (int k=0;k & lt;pd.length;k + +) {//8。如果相等,证明已经找到对应得属性 如果(pd [k] . getname () .equalsIgnoreCase(名字)){ 方法mSet=零;//9。利用反射,获取该属性组的方法 mSet=pd [k] .getWriteMethod ();//10。用原beanMap中该bean的实例,执行该属性组的方法,并从原beanMap中获取该属性的依赖值 mSet.invoke (beanMap.get (id), beanMap.get (ref)); } } 打破; } } }/* * *通过bean的id获取bean的实例 * * @param beanName * bean的id * @return返回对应对象 */公共对象getBean(字符串beanName) { 对象obj=beanMap.get (beanName); 返回obj; } }/* * *测试方法。 * * @param arg游戏 */公共静态void main (String [] args) {//使用我们自己写的BeanFactory BeanFactory工厂=new BeanFactory (); factory.init (“eat.xml”); 人javaBean=(人)factory.getBean(“人”); System.out.println (javaBean.eat ()); }用java的spring实现一个简单的国际奥委会容器示例代码