谈谈我对 IoC 和 AOP 的理解
@JFinal 波总在 JFinal 4.8 发布新闻的评论 中给出了下面的表述:
IOC 本质是为了实现 AOP
我有点吃惊, 没想到 Java 界的大佬对这两个概念有和我完全不一致的认识. 所以写下这篇博客, 并借此机会重新学习一下 IoC 和 AOP, 确保自己对这两个后端开发非常重要的概念不会有太过偏差的理解
1. IoC
IoC 是 Inversion of Control 的缩写, 中文意思是控制反转. 维基百科对 IoC 开宗明义的定位为:
In software engineering, inversion of control (IoC) is a programming principle
维基文中对此有详细的阐述, 大家可以自行前往维基百科 Inversion_of_control
词条查看, 我就不一一 Copy/Paste 了. 这里帮大家检出几个关键地方捋一捋:
- IoC 是编程原则 - 不是特定的产品, 不是具体实现方式, 当然也和具体编程语言无关
- 在传统编程范式中, 程序调用可重用的库
- 在 IoC 原则下, 程序接受通用框架的调用控制 - 框架调用程序代码
- 与 IoC 原则相关的概念包括:
- IoC 的设计目的包括:
- 将执行任务和任务实现解耦
- 让模块专注于设计任务
- 模块仅依赖于设计契约而无需关注其他系统如何工作
- 避免模块替换时的副作用
到这里我们可以比较清楚地得出下面的结论了:
J1. IoC 的本质不是为了实现 AOP.
J2. 波总的 JFinal 已经实现了 IoC 原则. 因为应用写的代码总是被 JFinal 的代码调用, 这就是控制反转.
那为什么波总会说 "IOC 本质是为了实现 AOP" 呢? 我姑且胡乱猜测一下, 波总想说的有可能是 "DI 本质是为了实现 AOP". 下面我们来探讨一下 DI, 这个和 IoC 以及 AOP 都有关系的概念.
2. DI
DI - Dependency Injection, 中文叫依赖注入, 在维基百科中的定义为:
In software engineering, dependency injection is a technique whereby one object supplies the dependencies of another object.
特别地, 维基百科中的 DI 词条给出了下面的描述:
Passing the service to the client, rather than allowing a client to build or find the service, is the fundamental requirement of the pattern.
The intent behind dependency injection is to achieve Separation of Concerns of construction and use of objects. This can increase readability and code reuse.
上面在对 DI 的描述中引入了另一个概念: SoC (Separation of Concern), 中文名关注点分离. 这是计算机科学中的一条设计原则, 简单地说就是将计算机程序划分为独立的单元, 每个单元解决一个可分离的关注点. 这个概念和封装 (Encapsulation) 非常接近, 可以说封装是对 SoC 设计原则的一种具体实现. 而 DI 则被描述为在构造和使用对象上实现 SoC 这个设计原则.
从上面的表述我们可以得到第二条结论:
J3. DI 也不是为了实现 AOP
那 DI 或者 IoC 到底和 AOP 有没有关系, 我们先来看看 AOP 的定义
3. AOP
AOP - Aspect Oriented Programming 在维基百科中的定义为:
In computing, aspect-oriented programming (AOP) is a programming paradigm that aims to increase modularity by allowing the separation of cross-cutting concerns.
这里面有几个关键点:
- AOP 是一个编程范式. 听上去有点晦涩, 下面列举几个编程范式的例子可以帮助大家理解这个概念:
- Imperative - 指令式, c, c++, Java
- Declarative - 声明式, SQL, 各种 DSL, 比如 ANTLR 的语法文件
- AOP 的目的是通过分离横切关注点(Separation of cross-cutting concern) 来提高模块性.
这里的 Separation of cross-cutton conern 是不是有点耳熟? 回顾上面提到的 DI 描述中引入的 Separation of Concern, 两个概念字面相近, 但又不完全一致. AOP 关注的是切面, 而 DI 关注的是对象构造. 如果没有注意到这个异同处, 有可能将 DI (甚至 IoC) 和 AOP 的概念搅和到一起.
扩展讨论
无独有偶, 前段时间 drinkjava (@yong9981) 同学也和我就 AOP 以及 DI 的关系进行了比较深入的探讨, 话题包括:
- AOP 的实现是否必须有 DI 提供
- Web 框架是否必须提供通用 AOP 的实现
- 声明式事务是否必须采用 AOP 来提供
对这些话题感兴趣的朋友可以继续访问 谈谈 Act 的依赖注入 和 模板输出 - 回 drinkjava 同学的评论.
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
素小暖讲JVM:第一章 走进Java,第二章 Java内存区域与内存溢出异常,第三章 垃圾收集器与内存分配策略
本系列是用来记录《深入理解Java虚拟机》这本书的读书笔记。方便自己查看,也方便大家查阅。 欲速则不达,欲达则欲速! 第一章 走进Java 一、Java虚拟机发展史 这部分一带而过吧,有兴趣的可以阅读原著! 二、Java内存管理,class文件结构与执行引擎,编译器优化,多线程并发的简单解释(后续章节详述) 自动内存管理讲的是Java运行时数据区里的部分分为内存划分和垃圾收集器 执行子系讲的是类文件管理、类加载机制、字节码执行引擎 优化分为编译器优化和运行期优化 并发讲的是虚拟机是如何实现多线程的 具体可以结合下面的jvm结构图来看,这张图是基于JDK1.7的。JDK1.7之前,常量池是存放在方法区中的,1.7之后常量池存放在堆中。 第二章 Java内存区域与内存溢出异常 我们知道在C++语言里,如果想使用一个对象,需要对其进行new操作,如果不用这个对象了,需要对其进行delete操作,一旦开发人员忘记写delete语句,就会造成内存泄漏。 而java就很聪明,它将手动改为自动,把内存的控制权交给了虚拟机,下面我们就来探究一下JVM是怎么进行自动内存管理的。 手动内存管理分为两部分:...
- 下一篇
python web ide/jailkit python环境安装 搭建
PythonIDE基础软件安装 PythonIDE 基于开源修改,地址为: https://github.com/vimior/PythonWebIDE.git 对其增加了 关键词验证、输出过滤、同步登录等功能。 为了安全性考虑,将用户从系统上隔离(没有采用docker)。隔离软件为 jailkit,本文只介绍jailkit的软件安装以及基于这个软件的pythonide 环境安装。 以下操作均需要 root用户操作,需要切换用户的都作说明了,注意看 Jailkit 安装 版本为:2.21 wget http://olivier.sessink.nl/jailkit/jailkit-2.21.tar.bz2 tar xf jailkit-2.19.tar.bz2 ./configure --prefix=/usr/local/src/jailkit-2.21 make make install 配置受限环境 注:受限不目录能与安装目录相同 mkdir -p /app/ideuser 设置在受限环境中可以运行的命令 jk_init -v /app/ideuser netutils b...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- Mario游戏-低调大师作品
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Red5直播服务器,属于Java语言的直播服务器
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS8编译安装MySQL8.0.19
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS6,CentOS7官方镜像安装Oracle11G
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装