如果没有没有亲自做过一些项目,直接上手就学spring那样的框架,你可能会觉得莫名其妙,有java就够了呀,为什么要学习这么一个陌生的东西。框架其实是软件的半成品,他提供的一些接口、功能,让你可以在他的基础上方便高效地开发,spring的ioc容器即是一例。
Ioc即控制反转,在spring中其实就是依赖注入。一个对象不可能单打独斗,它总要和其他对象进行交互合作,它通过构造参数,工厂方法参数或者对象属性定义其依赖关系,然后通过第三方容器(如spring ioc)在创建该对象时注入这些依赖,这就是控制反转,该对象即被称为bean,与之相反的是对象自身直接通过构造方法控制其依赖对象的实例化,或者通过ServiceLocator定位依赖对象,我们可以通过示例比较这两种方法。
比如你有个类控制对外部网站的数据爬取工作:
//抓取接口
public interface Crawl {
public void crawlPage();
}
//抓取京东网站内容的实现类
public class JingdongCrawler implements Crawl{
@Override
public void crawlPage() {
System.out.println("crawl Jingdong");
}
}
//抓取控制器
public class CrawlControl {
private Crawl crawler;
public CrawlControl(){
crawler = new JingdongCrawler();
}
public void execute(){
crawler.crawlPage();
}
}
注意看构造方法,他是直接在其中创建相应的依赖对象,即Jingdongrawler,这样他就和依赖对象有了一种紧密的耦合关系,这是违反软件开发中松耦合的原则的,如果我们要抓取淘宝网站,是不是要再写一个CrawlControl2,来实例化TaobaoCrawler 呢,或者我们可以用Service Locator模式,通过中间代理类来实现松耦合,但对象还是要自己去获取管理这些依赖对象,有没有一种方式,使得对象仅仅需要通过构造参数或者属性定义依赖关系,而其依赖对象的创建,管理统统交给第三方容器呢,答案就是Ioc容器
//抓取淘宝网站内容的实现类
public class TaobaoCrawler implements Crawl{
@Override
public void crawlPage() {
System.out.print("crawl taobao");
}
}
//CrawlControl 在ioc容器中的写法
public class CrawlControl {
private Crawl crawler;
public CrawlControl(Crawl crawler){
this.crawler = crawler;
}
public void execute(){
crawler.crawlPage();
}
}
CrawlControl 构造方法中并不实例化具体crawler,而是交给ioc容器处理,ioc容器会读取配置元数据(如XML配置),知道他绑定的是哪个具体实例(既可以指定为taobaoCrawler,又可以指定为jingDongCrawler,比原来更加通用 ),然后创建,绑定,装配相应的对象。比如你在配置中指定ref='taobaoCrawler',容器帮你做的工作相当于:
CrawlControl control = new CrawlControl(new TaobaoCrawler ());
而你需要做的仅仅是获取装配创建好的对象,调用方法:control.execute();
当然容器的内部的工作流程其实复杂得多,关于如何编写相应的xml配置文件,如何从容器中获取所需对象,这个都属于使用的范畴。写这篇文章主要是告诉大家使用框架之前要明白为什么去用,主要是为了解决什么问题,而不是人云亦云,随大流,你掌握了原理,掌握了基础,自己也可以开发一套框架出来,框架是伴着实际问题,为了解决实际问题而出现的。