为什么需要Spring Ioc
如果没有没有亲自做过一些项目,直接上手就学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配置文件,如何从容器中获取所需对象,这个都属于使用的范畴。写这篇文章主要是告诉大家使用框架之前要明白为什么去用,主要是为了解决什么问题,而不是人云亦云,随大流,你掌握了原理,掌握了基础,自己也可以开发一套框架出来,框架是伴着实际问题,为了解决实际问题而出现的。
- Python Selenium设计模式-POM
- [快学Python3]HTTP处理 - urllib模块
- Vijos P1786 质因数分解【暴力】
- 模仿百度新闻列表底部的“加载更多”
- Vijos P1035 贪婪的送礼者【模拟】
- Vijos P1114 FBI树【DFS模拟,二叉树入门】
- Vijos P1448 校门外的树【多解,线段树,树状数组,括号序列法+暴力优化】
- 撞库扫号防范
- 分享一个 HTTPS A+ 的 nginx 配置
- Vijos P1785 同学排序【模拟】
- Vijos P1784 数字统计【模拟】
- 网络安全黑暗森林法则:2015 ISC 深度回顾
- Codeforces 626G Raffles(贪心+线段树)
- window.opener.location 安全风险讨论
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 虽然现在有可以去码的软件了,可视频是如何自动跟踪打码的?
- 2020-09-12:手撕代码:最小公倍数,复杂度多少?
- Mac App推荐
- 美团面试问ThreadLocal,学妹一口气给他说了四种!
- BFE.dev前端刷题#108. 用队列(Queue)实现栈(Stack)
- Kafka消费过程关键源码解析
- leetcode链表之两个链表的第一个公共节点
- 测试开发基础 mvn test | 利用 Maven Surefire Plugin 做测试用例基础执行管理
- 腾讯云Elasticsearch集群规划及性能优化实践
- 【赵渝强老师】在MongoDB中使用MapReduce方式计算聚合
- 2020-09-13:判断一个正整数是a的b次方,a和b是整数,并且大于等于2,如何求解?
- ASP.NET Core 性能优化最佳实践
- 如何在Vue中使用云开发的云函数,实现邮件发送
- 乐观锁与悲观锁
- 为什么配置文件加密了数据库配置信息,Spring Boot仍能成功连接数据库