Spring初学笔记(一):Spring IOC的理解
关于依赖注入、控制反转
Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。
在我看来,这句话已经很好的体现了出来IOC思想在编程中的体现形式,而采用这样的思想,可以大大降低类与类之间的耦合度,便于代码的扩展。
这里,我们看一个简单的例子:
我们假设有人和车,他们的类分别如此:
public interface Car {
public void run();
}
public interface Person {
public void Travel();
}
首先定义两个接口,表示要实现的车的功能和人的功能,而在实现人的功能时,旅游总不能光着脚出去吧,假设我们需要一辆车才能出行:
public class BenzCar implements Car{
@Override
public void run() {
System.out.println("奔驰车在跑");
}
}
public class Man implements Person {
private Car car;
public Man(){
car = new BenzCar();
}
@Override
public void Travel() {
System.out.println("我有车了");
car.run();
}
}
这是对应实现好的人类和车类,其中人类依赖于车类,他现在要自己创建一个车的对象,才能实现对应的功能。
我们测试一下这个代码可不可以运行:
public class Test {
public static void main(String[] args) {
Person person = new Man();
person.Travel();
}
}
执行以后,代码可以正常运行,但现在有一个问题,如果这个人过几天有钱了,不想用奔驰了,想换车,那怎么办呢。现在的代码,有一个很明显的问题,就是人和车类的耦合度太高,其原因就是在Man类的内部,自己创造了对应车类的对象,这就导致如果要想修改,只能对Man类的源码进行修改,这也就不符合“对修改关闭,对扩展开放”的原则了。
对这个问题的解决办法就是:不要从内部创建对象,而是由外部传入对象,你只要接收就可以了。
在更改后的代码为:
public class Man implements Person {
private Car car;
public Man(Car car){
this.car = car;
}
@Override
public void Travel() {
System.out.println("我有车了");
car.run();
}
}
将对应的Car类对象的生成方法,由自己new出来,变成通过构造参数传入(当然传入的方法不止一种,像set之类的方法也是可以的,这里只以构造方法为例)
现在对于Man类的扩展问题,我们已经解决了,就算他换成什么车,我们都可以直接在main函数中创建对应的对象,然后直接传入即可。
做到这里,像我这样从来没有大型编程经验的人就觉得已经很好了呀,我不用修改源代码,只要自己在主函数中创建对象,通过我设定的构造器呀set呀等方法传入就可以让程序正常运行啦。
但有多年开发经验的程序员们觉得还不大行,确实这样可以满足了代码复用和开闭原则,但你这样做有一个前提条件,就是你自己熟悉自己所写的全部类,可以明确他们的关系,才能够创建出对应的实体类,但如果是多人开发呢,如果一个人只负责一个模块,那会发生什么样的情况。
从上面我们可以看到,创建一个人的对象,我们需要显式地注入Car的对象,我们很清楚这一点,所以我们可以创造出man类的对象,但如果是多人合作,比如我是写service层的人员,我想调用person的travel()接口,但发现没有实体类,我需要构建。我new一个实体类,结果编译器报错误,我找了半天没找出来哪里有错,最后对Dao管理的人给我说,这个你要传进去一个Car类的对象,其中Car类对象有.xxx,sss之类。
我只是需要调用对象的接口,但这样的注入方法,让我必须清楚对象是如何创建的,而且还要为这个构建去new一个Car对象,这些都是完全不应该由我这样一个写service层的人来做的工作,为了解决这个问题,我们可以采用工厂模式。
先创建一个单例的工厂:
public class Factory {
private Factory() {
} public static Factory getInstance() {
return inner.instance;
} private static class inner {
private static final Factory instance = new Factory();
} }
在工厂中,我们可以创建Man对象:
public Person getMan(){
return new Man(new BenzCar());
}
这样,我们在外部调用的时候,只需要获得工厂,然后通过工厂的方法得到所需对象了,不再需要关心对象到底是如何生成的了。
public static void main(String[] args) {
Factory factory = Factory.getInstance();
Person person = factory.getMan();
person.Travel();
}
原本是调用者直接创建对象,现在改成了通过工厂这个容器,来直接获取对象。
这样,通过工厂方式+注入对象的方法,我们实现了类与类之间的解耦,也完成了生产时调用者只需使用类,而不用关心创建类的功能。
下一篇,我们了解一下在Spring中,对象是如何注入的。
Spring初学笔记(一):Spring IOC的理解的更多相关文章
- Spring 初学笔记
Spring 初学笔记: https://blog.csdn.net/weixin_35909255/article/category/7470388
- Spring初学笔记(二):Bean的注入
关于Bean的注入 在上一篇中,已经说到虽然注入确实可以降低类与类之间的耦合,但并没有解决调用者必须知道类的创建方法的问题,也可以说是没有实现调用者与类实现的解耦,我们也提到,为了实现两者的解耦,可以 ...
- spring学习笔记(一) Spring概述
博主Spring学习笔记整理大部分内容来自Spring实战(第四版)这本书. 强烈建议新手购入或者需要电子书的留言. 在学习Spring之前,我们要了解这么几个问题:什么是Spring?Spring ...
- Java架构师之路 Spring学习笔记(一) Spring介绍
前言 这是一篇原创的Spring学习笔记.主要记录我学习Spring4.0的过程.本人有四年的Java Web开发经验,最近在面试中遇到面试官总会问一些简单但我不会的Java问题,让我觉得有必要重新审 ...
- Spring 学习笔记(2) Spring Bean
一.IoC 容器 IoC 容器是 Spring 的核心,Spring 通过 IoC 容器来管理对象的实例化和初始化(这些对象就是 Spring Bean),以及对象从创建到销毁的整个生命周期.也就是管 ...
- Spring 读书笔记-----使用Spring容器(一)
pring有两个核心接口:BeanFactory和ApplicationContext,其中ApplicationContext是BeanFactory的子接口.他们都可代表Spring容器,Spri ...
- (转)Spring 读书笔记-----使用Spring容器(一)
Spring有两个核心接口:BeanFactory和ApplicationContext,其中ApplicationContext是BeanFactory的子接口.他们都可代表Spring容器,Spr ...
- Spring学习笔记--环境搭建和初步理解IOC
Spring框架是一个轻量级的框架,不依赖容器就能够运行,像重量级的框架EJB框架就必须运行在JBoss等支持EJB的容器中,核心思想是IOC,AOP,Spring能够协同Struts,hiberna ...
- Spring Boot笔记十:IOC控制反转
目录 IOC控制反转和DI依赖注入 IOC实现Hello World Spring IOC容器怎么知道哪些是管理的对象? IOC容器getBean方法的三种签名 xml配置文件的import导入 @A ...
随机推荐
- 使用Idea当中的快捷键快速查看继承关系或其图表的两种方法
一.Idea当中有两种方法可以查看继承关系 在Idea当中选中一个类,然后按Ctrl+H,可以快速查看当前所选类的继承关系,如下图: 同样选中一个类,按CTRL+ALT+U,即可生成当前类的继承关 ...
- 9、flink的状态与容错
1.理解State(状态) 1.1.State 对象的状态 Flink中的状态:一般指一个具体的task/operator某时刻在内存中的状态(例如某属性的值) 注意:State和Checkpoint ...
- xpath进阶用法
一.简介 xpath作为对网页.对xml文件进行定位的工具,速度快,语法简洁明了,在网络爬虫解析内容的过程中起到很大的作用,除了xpath的基础用法之外xpath中还存在着非常之多的进阶用法,本文将对 ...
- php中&&和and有什么区别
PHP中的逻辑“与”运算有两种形式:AND 和 &&,同样“或”运算也有OR和||两种形式. 如果是单独两个表达式参加的运算,两种形式的结果完全相同,例如 $a AND $b和$a & ...
- CRS-0184 Cannot communicate with the CRS daemon
事件背景 rman清理脚本异常.导致磁盘空间爆满(一个环境变量没有设置正确) 释放磁盘空间,进行rman清理 之后,领导把实例重启,但是ams实例没有关闭 环境 系统 : AIX 数据库: Oracl ...
- vue项目中使用bpmn-为节点添加颜色
内容概述 本系列 “vue项目中使用bpmn-xxxx” 分为五篇,均为自己使用过程中用到的实例,手工原创,目前属于陆续更新中.主要包括vue项目中bpmn使用实例.应用技巧.基本知识点总结和需要注意 ...
- vue-cli3.0 gui初体验
为什么80%的码农都做不了架构师?>>> 介绍 新版的vuecli3.0提供了一个vue ui这个命令,这个命令是做什么的呢,这里引用官网的一段介绍 vue ui 你可以通过 v ...
- 写给MongoDB开发者的50条建议Tip21
本系列文章翻译自<50 Tips and Tricks for MongoDB Developers>,暂时没有找到中文版,反正自己最近也在深入学习mongodb,所以正好拿来翻译一下.一 ...
- 一张图告诉你E-R图怎么画
E-R图也称实体-联系图(Entity Relationship Diagram),提供了表示实体类型.属性和联系的方法,用来描述现实世界的概念模型. 它是描述现实世界关系概念模型的有效方法.是表示概 ...
- 如何用Hexo搭建个人博客
以前用Wordpress搭建过一个博客网站,Wordpress虽然安装简单,功能强大,但是对于个人建站来说有点复杂了.最近发现用Hexo建站很流行,于是将网站从Wordpress迁移到了Hexo. H ...