前言

Spring框架通过POJO最小侵入性编程、DI、AOP、模板代码手段来简化了Java 开发,简化了企业应用的开发。POJO和模板代码相对来说好理解,本篇重点解读下DI和AOP。

一 DI

DI(依赖注入)定义

对象的依赖关系将由系统中负责协调各对象的第三方组件在创建对象的时候进行设定。对象无需自行的创建或管理它们的依赖关系。

背景和问题

我们行来假设没有Spring 来管理注入依赖关系,我们是怎么来实现依赖关系管理的,直接在对象内部通过new进行创建对象,每个对象负责管理与自己相互协作的的对象(即它所依赖的对象)的引用,是程序主动去创建依赖对象。下面的一段代码是在没有用Spring 来实现DI的情况下,我们是怎么做的,这样做的问题在哪?

1.高度的耦合,RecognitionServiceImpl 和ContractRepository 两者耦合在一起。

2.难以测试,如果我们想测试RecognitionService,在不改代码下很难来测试。

public class RecognitionServiceImpl implements RecognitionService {
ContractRepository contractRepository = new ContractRepository();
}

解决方案

通过DI,对象的依赖关系将由系统中负责协调各对象的第三方组件在创建对象的时候进行设定。对象无需自行的创建或管理它们的依赖关系。DI带来的最大的收益是——松耦合。其次是面向接口依赖的可替换(常用的是测试的时候使用mock实现)

在Spring 框架中怎么来实现DI呢?

在Spring中创建应用组件之间的协作方式通常称为装配(wiring)。它提供了三种装配实现方式,分别是XML装配、JavaConfig装配、自动装配。

Spring 的装配方式

XML装配(在XML中显示配置)

JavaConfig装配(基于Java的配置 )

自动化装配

Spring从两个角度实现自动化装配

组件扫描(component scanning) : Spring会自动发现应用上下文中所创建的bean 

自动装配(autowiring) : Spring自动满足bean之间的依赖。

简单来说,DI目的只有一个就是解耦,实现代码的松散耦合。高耦合的代码不易测试、不易复用。

二、AOP

AOP的定义

AOP,面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑外的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。是不是有点不太好理解。我们先有个概念上的认识,就是面向切面编程。所谓切面,横切关注点模块化为特殊的类,这些类被称为切面。

背景和问题

理解AOP最关键的点是先理解横切关注点,所谓的横切关注点是指散布于应用中的多处功能。最典型的横切关注点有日志记录、性能统计、安全控制、事务处理、异常处理、缓存等。这些横切的关注点从概念上与应用的业务逻辑相分离的(但是往往会直接嵌入到应用的业务逻辑中去)。没有AOP,我们往往会把这些横切的关注点来直接嵌入到业务逻辑中去,这样做的一个问题是什么?一是分散在多处,就是这类的代码分散在多处代码中,重复出现。二是 与业务代码耦合在一起。把这些横切关注点与业务逻辑相分离,解耦是面向切面编程(AOP)要解决的问题。

解决方案

通过AOP 来解决横切关注点与业务逻辑相分离解耦。横切关注点要以描述为影响多处的功能,例如:安全就是一个横切关注点,应用中的许多方法都会涉及到安全规则,事务也是一个横切关注点,应用在很多方法中。

横切关注点可以被模块化为特殊的类,这些类被成为切面(aspect)。切面有两个好处,一是每个关注点都集中于一个地方,二服务模块更加的简洁,只需主要关注于业务逻辑,像安全,事务等次要的关注点被转移到了切面中。

AOP术语

AOP已经有了自己的一些术语。描述切面的常用术语有通知(advice)、切点(point)、和连接点。

通知(advice)

在aop 术语中,切面的工作被成为通知。通知定义了切面是什么以及何时使用。通知有两个功能,一个是描述切面要做什么?另一个是何时做。简单来说是在某个方法被调用之前执行,还是之后执行,还是之前之后都要执行,还是只在方法抛出异常是执行。

Spring 切面可以应用5种类型的通知。

  1. 前置通知(Before):在目标方法被调用之前调用通知功能。
  2. 后置通知(After):在目标方法完成之后调用通知,此时不关心方法的输出是什么。
  3. 返回通知(After-returning):在目标方法成功执行之后调用通知。
  4. 异常通知(After-throwing):在目标方法抛出异常后调用。
  5. 环境通知(Around):通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为。

连接点(Join Point)

应用有很多的时机去应用(调用通知),这些时机被称为连接点。连接点是应用执行过程中能够插入切面的一个点。这个点可以是调用方法时,抛出异常时,甚至是修改一个字段时。切面代码可以利用这些点插入到应用的正常流程之中,并添加新的行为。

切点(Poincut)

如果通知定义了切面的”什么(what)“和”何时(when)" 的话,那么切点就定义了“何出(where)"。切点的定义会匹配要织入的一个或多个连接点。通常使用明确的类和方法名称,或者是利用正则表达式来定义所匹配的类和方法名来指定切点。

切面(Aspect)

切面是通知和切点的结合,通知和切点来定义了切面的全部内容,它是什么,在何时何处完成其功能。

引入(Introduction)

引入允许向现有的类添加新方法和属性。

织入(Weaving)

织入是把切面应用到目标对象并创建新的代理对象的过程。切面在指定的连接点被织入到目标对象中。在目标对象的生命周期中有多个点可以织入。编译期(AspectJ),类加载期(AspectJ5 支持),运行期(Spring Aop 以这种方式织入切面的)。

总结一下:通知包含了需要应用多个应用对象的横切行为;连接点是程序执行过程中能够应用通知的所有点;切点定义了通知被应用的具体位置(即哪些连接点)。简而言之:切点定义了哪些连接点会得到通知。

Spring 对AOP的支持

创建切点来定义切面所织入的连接点是AOP框架的基本功能。

Spring 提供了4种AOP的支持。

  1. 基于代理的经典Spring Aop
  2. 纯POJO切面
  3. @AspectJ 注解驱动的切面
  4. 注入式AspectJ 切面(适用于Spring 各版本)

前三种都是Spring Aop 的变体,SpringAop 构建在动态代理基础之上(即基于动态代理),Spring对AOP的支持局限于方法拦截。

理解了这些概念后如何应用Spring AOP就相对而言来说简单的多了。

总结

DI目的只有一个就是解耦,实现代码的松散耦合。解决高耦合的代码带来的不易测试、不易复用的问题。

AOP解决的问题是如何把应用中横切关注点与业务逻辑相分离,解耦。把之前分散在应用各处的行为放入可重用的模块中,有效减少了代码冗余,并让类更关注于自身的主要功能和业务逻辑。

如何快速理解Spring中的DI和AOP的更多相关文章

  1. 理解Spring中的IOC和AOP

    我们是在使用Spring框架的过程中,其实就是为了使用IOC,依赖注入和AOP,面向切面编程,这两个是Spring的灵魂. 主要用到的设计模式有工厂模式和代理模式 IOC就是典型的工厂模式,通过ses ...

  2. 5分钟简述Spring中的DI与AOP

    Spring的两个核心特性: 依赖注入(dependency injection,DI) 面向切面编程(aspect oriented programming,AOP) 依赖注入(dependency ...

  3. 深入理解spring中的各种注解

    Spring中的注解大概可以分为两大类: 1)spring的bean容器相关的注解,或者说bean工厂相关的注解: 2)springmvc相关的注解. spring的bean容器相关的注解,先后有:@ ...

  4. 深入理解spring中的各种注解(转)

    Spring中的注解大概可以分为两大类: 1)spring的bean容器相关的注解,或者说bean工厂相关的注解: 2)springmvc相关的注解. spring的bean容器相关的注解,先后有:@ ...

  5. 通过BeanPostProcessor理解Spring中Bean的生命周期

    通过BeanPostProcessor理解Spring中Bean的生命周期及AOP原理 Spring源码解析(十一)Spring扩展接口InstantiationAwareBeanPostProces ...

  6. 详谈 Spring 中的 IOC 和 AOP

    这篇文章主要讲 Spring 中的几个点,Spring 中的 IOC,AOP,下一篇说说 Spring 中的事务操作,注解和 XML 配置. Spring 简介 Spring 是一个开源的轻量级的企业 ...

  7. Spring中基于xml的AOP

    1.Aop 全程是Aspect Oriented Programming 即面向切面编程,通过预编译方式和运行期动态代理实现程序功能的同一维护的一种技术.Aop是oop的延续,是软件开发中的 一个热点 ...

  8. 理解Spring中的IoC和DI

    什么是IoC和DI IoC(Inversion of Control 控制反转):是一种面向对象编程中的一种设计原则,用来减低计算机代码之间的耦合度.其基本思想是:借助于"第三方" ...

  9. 用通俗的语言解释 Spring 中的 DI 、IOC 和AOP概念

    DI 所谓依赖,从程序的角度看,就是比如A要调用B的方法,那么A就依赖于B,反正A要用到B,则A依赖于B.所谓倒置,你必须理解如果不倒置,会怎么着,因为A必须要有B,才可以调用B,如果不倒置,意思就是 ...

随机推荐

  1. Java匹马行天下之JavaSE核心技术——异常处理

    Java匹马行天下之JavaSE核心技术——异常处理 异常的简介 在Java中,异常就是Java在编译.运行或运行过程中出现的错误. 程序错误分为三种:编译错误.运行时错误和逻辑错误 编译错误是因为程 ...

  2. Hash记录字符串

    Hash记录字符串模板: mod常常取1e9+7,base常常取299,,127等等等....有的题目会卡Hash,因为可能会有两个不同的Hash但却有相通的Hash值...这个时候可以用双Hash来 ...

  3. Pet BFS

    一天早上小明醒来时发现他的宠物仓鼠不见了. 他在房间寻找但是没找到仓鼠. 他想用奶酪诱饵去找回仓鼠. 他把奶酪诱饵放在房间并且等待了好几天. 但是可怜的小明除了老鼠和蟑螂没见到任何东西. 他找到学校的 ...

  4. 再看CVE-2018-12613 phpmyadmin后台文件包含&&RPO攻击

    写在前面 因为看了朋友的一篇分析又回头想了想自己去年遇到的这个纠结的问题. 去年写过一篇phpmyadmin后台文件包含的文章,写的非常的草草,并没有分析的过程,只是把自己的问题记了下来.当时纠结于最 ...

  5. 二分查找(通过相对位置判断区间位置)--17--二分--LeetCode33搜索旋转排序数组

    搜索旋转排序数组 假设按照升序排序的数组在预先未知的某个点上进行了旋转.( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] ). 搜索一个给定的目标值,如果数组中 ...

  6. JS面向对象编程之封装

    来源:https://segmentfault.com/a/1190000015843072 我们所熟知的面向对象语言如 C++.Java 都有类的的概念,类是实例的类型模板,比如Student表示学 ...

  7. opencv-0-项目启程

    opencv-0-项目启程 opencvC++QT 开始 无数次说要开始 opencv 的系列, 但是都由于各种原因没有坚持下去, 这次我做最后一次尝试, 也做最后一次坚持, 如果不做下去, 我就再也 ...

  8. 理解分布式一致性:Paxos协议之Multi-Paxos

    理解分布式一致性:Paxos协议之Multi-Paxos Multi-Paxos without failures Multi-Paxos when phase 1 can be skipped Mu ...

  9. @SessionAttributes 和 @SessionAttribute的区别

    @SessionAttributes 和 @SessionAttribute的区别 Spring MVC中有两个长得非常像的注解:@SessionAttributes 和 @SessionAttrib ...

  10. Linux系统管理第四次作业 磁盘管理 文件系统

    1.为主机新增两块30GB的SCSI硬盘 2.划分3个主分区,各5GB,剩余空间作为扩展分区 [root@localhost ~]# fdisk /dev/sdb 欢迎使用 fdisk (util-l ...