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 ...
随机推荐
- JasperReports入门教程(四):多数据源
JasperReports入门教程(四):多数据源 背景 在报表使用中,一个页面需要打印多个表格,每个表格分别使用不同的数据源是很常见的一个需求.假如我们现在有一个需求如下:需要在一个报表同时打印所有 ...
- 关于Google下插件SwitchyOmega用法
开启代理后,尽管访问很自由了,但是我的搬瓦工,是有流量限制的.所以,在之前,我开启一会自由访问模式(戏称),然后关一会,用来方便打开国内网站. 是的,我这么坚持了半个月,之后,就崩溃了,太尼玛繁琐了! ...
- iOS appium
1.如果没有安装过Homebrew,先安装homebrew /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/ ...
- Apk优化极致
1. webp WebP格式,谷歌(google)开发的一种旨在加快图片加载速度的图片格式.图片压缩体积大约只有JPEG的2/3,并能节省大量的服务器宽带资源和数据空间.Facebook Ebay等知 ...
- http与web
在看<图解http>的时候,忽然有一个想法冒出来. web与http是什么关系? http服务器与web服务器有区别?为什么用以搞混了? web的定义:它是一种基于超文本和HTTP的.全球 ...
- 自动驾驶汽车数据不再封闭,Uber 开源新的数据可视化系统
日前,Uber 开源了基于 web 的自动驾驶可视化系统(AVS),称该系统为自动驾驶行业带来理解和共享数据的新方式.AVS 由Uber旗下负责自动驾驶汽车研发的技术事业群(ATG)开发,目前该系统已 ...
- 信息竞赛进阶指南--递归法求中缀表达式的值,O(n^2)(模板)
// 递归法求中缀表达式的值,O(n^2) int calc(int l, int r) { // 寻找未被任何括号包含的最后一个加减号 for (int i = r, j = 0; i >= ...
- linux多线程同步的四种方式
1. 在并发情况下,指令执行的先后顺序由内核决定.同一个线程内部,指令按照先后顺序执行,但不同线程之间的指令很难说清楚是哪一个先执行.如果运行的结果依赖于多线程执行的顺序,那么就会形成竞争条件,每次运 ...
- 题目分享H 二代目
题意:有m个限制,每个限制l1,r1,l2,r2四个数,限制了一个长度为n的数第l1到r1位要与第l2到r2相同,保证r1-l1=r2-l2,求在限制下一共有多少种数 分析: 暴力的话肯定是从l1-r ...
- centos8-django项目部署 nginx+uwsgi
1.虚拟环境virtualenv安装 1.安装virtualenv pip3 install virtualenv 2.创建目录,把项目文件传过来 mkdir My cd My 3.创建独立运行环境- ...