渣渣,叔被面过这么多次,怎么可能不会扯ioc,不过如果做一个,或许比扯更有意思,以下为我自学ioc的路线
一:我先整个ioc:我记得ioc最著名的容器是spring,形式上是用配置文件进行类的创建...大致路线为xml->map->bean,知道这些我就可以先走一个
1.bean:ioc容器存的是bean,我最好现有一个bean,属性最好少一点,这样不至于太尴尬
package bean; public class Student { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
2.xml:我知道xml是什么,但是...
nothing,度个娘,大致是这么个样子,这样的话我的ioc容器就可以长成这个样子
<?xml version="1.0" encoding="UTF-8"?> <ioc> <bean id="english" class="bean.Student"> <name>李雷</name> </bean> <bean id="chinese" class="bean.Student"> <name>韩梅梅</name> </bean> </ioc>
3.xml->map,将配置文件读取到map/内存中
1.我需要了解路径的寻找,我有点忘了,我得参考下获取文件的方式
2.对xml的操作,我知道有个dom4j,但是我没用过,不过我有api
package ioc; import java.io.File; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.commons.beanutils.BeanUtils; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; @SuppressWarnings({"unchecked","rawtypes"}) public class Init { private static Map<String, Object> ioc = new HashMap<String, Object>(); public static Object getBean(String key){ return ioc.get(key); } public Init(){ try { readXml("src/ioc.xml"); } catch (Exception e) { e.printStackTrace(); } } public static void readXml(String file) throws Exception { Document doc = load(file); Element root = doc.getRootElement(); for (Iterator iterator = root.elementIterator(); iterator.hasNext();) { Element e = (Element) iterator.next(); String _id = e.attributeValue("id"); String _class = e.attributeValue("class"); List<Element> list = e.elements(); Map<String, String> map = new HashMap<String, String>(); for (Element _e : list) { map.put(_e.getName(), _e.getText()); } Object obj=Class.forName(_class).newInstance(); BeanUtils.populate(obj, map); ioc.put(_id, obj); } } public static Document load(String filename) { Document document = null; try { document = new SAXReader().read(new File(filename)); } catch (Exception ex) { ex.printStackTrace(); } return document; } }
4.test
public static void main(String[] args) { new Init(); Student english = (Student) Init.getBean("english"); Student chinese = (Student) Init.getBean("chinese"); System.out.println("我是英语课代表:"+english.getName()); System.out.println("我是语文课代表:"+chinese.getName()); }
思考:他/ioc突然给了我一种变量的感觉,如果没有变量,就算是局部变量,那也会照成混乱,恶心,难受的情况(他们说这叫耦合),而变量解决了这个方法中的这个情况,ioc难道不是整个程序中专门提供变量类(变类)的一个方式?那样的话如果需要写ioc作用或者意义的话,就可以抄变量的(作用和意义的文章)了
总结:ioc就是为整个程序提供变量类
二:度娘ioc的理解:就好像看到新大陆一样,我迫不及待的度了个娘
度娘解释,维基解释:这些解释感觉就像神仙打架,也就凑个热闹,捧个人场,当当炮灰...不过注意到设计模式,和依赖注入的实现方式到让我想起了GOF第一种模式
女朋友解释,齿轮解释:非常形象的解释
三:策略模式与ioc容器的使用:记得我刚才想到的GOF第一种模式把,果断捞出来用用-->这里用spring,我的ioc不支持ref--!
将策略模式最后测试用例改一下,其中xml为:
<bean id="FlyNoWay" class="gof.fly.FlyNoWay"></bean> <bean id="FlyRocketPowered" class="gof.fly.FlyRocketPowered"></bean> <bean id="FlyWithWings" class="gof.fly.FlyWithWings"></bean> <bean id="MuteQuack" class="gof.quack.MuteQuack"></bean> <bean id="Quack" class="gof.quack.Quack"></bean> <bean id="Squeak" class="gof.quack.Squeak"></bean> <bean id="绿毛鸭" class="gof.Duck"> <property name="name" value="绿毛鸭"></property> <property name="flyBehavior" ref="FlyWithWings"></property> <property name="quackBehavior" ref="Quack"></property> </bean> <bean id="红头鸭" class="gof.Duck"> <property name="name" value="红头内裤外穿鸭"></property> <property name="flyBehavior" ref="FlyRocketPowered"></property> <property name="quackBehavior" ref="Squeak"></property> </bean> <bean id="模型鸭" class="gof.Duck"> <property name="name" value="模型鸭"></property> <property name="flyBehavior" ref="FlyNoWay"></property> <property name="quackBehavior" ref="MuteQuack"></property> </bean>
测试为:
ClassPathXmlApplicationContext ctx =new ClassPathXmlApplicationContext("applicationContext.xml"); ((Duck) ctx .getBean("绿毛鸭")).display(); ((Duck) ctx .getBean("红头鸭")).display(); ((Duck) ctx .getBean("模型鸭")).display();
至于结果,你懂得:
看,鸭子
绿毛鸭
正在用翅膀飞行
嘎嘎叫
看,鸭子
红头内裤外穿鸭
坐火箭飞
吱吱叫
看,鸭子
模型鸭
不会飞
不会叫
总结:如果ioc是一种模式,那一定是策略模式+工厂模式,也可以说是具有初始化功能(可配置)的工厂模式,当然,如果你要面试千万不要学我,说多了都是鼻涕...
四:我需要个能在web上跑的ioc:我了解到了ioc的模式,可我希望我的ioc也能在web项目下运行,在web下初始化其实程序,不要太简单
创建一个servlet用来初始化ioc,并指定此ioc在运行时进行加载
<servlet-mapping> <servlet-name>InitServlet</servlet-name> <url-pattern>/servlet/InitServlet</url-pattern> </servlet-mapping> <servlet> <servlet-name>InitServlet</servlet-name> <servlet-class>ioc.InitServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet>
思考:web.xml运行的顺序有4种,那我岂不是可以有4种启动方式?
五:我的ioc和spring的区别:既然ioc这么简单,为毛要用spring?仅仅是因为不重复造轮子?
xml:我看了下spring的配置文件和我的不一样,最开始我觉得,没什么大不了的,理解不一样而已,不过看到dtd的时候,秒懂
web.xml:启动方式果然有好几种
其他相关功能:看jar包就知道,它提供的功能更多
六:照虎画猫版
spring的提供很多简易的方式,叔自己不会写吗?话说写完之后感觉没那么大,他们源码里到底赛的是什么。。。
七:写完总结
回见
八:个大ioc使用比较(随便找点ioc框架以证明我用过很多ioc框架,而spring不愧是spring)
Guice:Google公司开发的轻量级IoC容器
PicoContainer:它利用了Inversion of Control模式和Template Method模式,提供面向组件的开发、运行环境(我喜欢微型的)
Jdon:国产
............
比较后总结:1.类似的框架越来越多,代码越来越少,速度越来越快,看来得重新理解不要重复制作轮子了。。
2.深深地感觉到这个充满恶意的社会....javascript的ioc是个毛意思
八:源码(spring太牛b了,先看微型的)
姑娘们看源码理解的时间到了,重在理念,设计/封装方式,其他略