我为大家简单介绍了一下Spring框架核心内容中的IoC,接下来我们继续讲解另一个核心AOP(Aspect Oriented Programming),即面向切面编程。

1、OOP回顾

在介绍AOP之前先来回顾一下大家都比较熟悉的OOP(Object Oriented Programming)。OOP主要是为了实现编程的重用性、灵活性和扩展性。它的几个特征分别是继承、封装、多态和抽象。OOP重点体现在编程架构,强调的是类之间的层次关系。

2、OOP缺陷

为了更好的说明OOP的概念,我们接下来讲一个OOP的实例,重点分析OOP存在哪些缺陷,以便更好的理解AOP的相关内容。

先看如下的一张图:

上面这张图有三个类:Dog,Cat和Duck,他们都有一个方法run。按照OOP的设计理念,我们很容易就会想到抽象出一个Animal父类,同时让这三个子类继承Animal父类。这样的设计可以用如下的图示表示:

在OOP思想中,我们会使用大量的类似上图的编程方式,对类进行抽象、继承、封装和多态来实现编程的重用性、灵活性和扩展性。但是这样的编程仍然有一定的局限性,有时候,OOP并不能很好解决我们再实际开发中遇到的问题。为了说明这个问题,看下面的图示:

看到上面的图,我们暂时还不能发现有什么问题。为了大家便于理解,接下来我来给大家讲解一下上面类图的实现过程。描述如下:马戏团有一条表演的小狗,这条小狗可以跑和跳,但是它完成跑和跳两个动作之前必须是在接到驯兽师发出的命令后,同时完成跑和跳的动作之后,驯兽师会给与响应的奖励,比如一块肉。

了解了实现过程之后,我们在来看一下具体的代码。

public class Dog {
public void run() {
System.out.println("驯兽师发出命令!")
System.out.println("小狗开始跑!");
System.out.pringln("驯兽师给与奖励");
}
public void jump() {
System.out.println("驯兽师发出命令!")
System.out.println("小狗开始跳!");
System.out.pringln("驯兽师给与奖励");
}
}

仔细看上面的代码,我们可以看出在run方法和jump方法中,存在一些相同的内容(驯兽师发出命令和给与奖励),这些内容并不能完全进行抽象,即不能按照OOP编程思想进行处理。类似这样的情况同样会出现在我们编程中的很多地方,例如:日志记录、性能统计、安全控制、事务处理、异常处理等等。但是这样的情况该如何解决呢?这就引入了AOP编程思想。

3、AOP简介

AOP为Aspect Oriented Programming的缩写,即面向切面编程(也叫面向方面),是一种可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。

4、AOP实现实例

为了大家更好的理解AOP如何实现,接下来我们优化一下上述代码。

首先是Dog类

 public interface Animal {
public void run();
public void jump();
} public class Dog implements Animal{
public void run(){
System.out.println("小狗开始跑!");
}
public void jump(){
System.out.println("小狗开始跳!");
}
}

对比之前的代码我们可以明显看出,我们将关于驯兽师的相关内容从run和jump中进行了抽取,接下来,我们如何在程序运行中将关于驯兽师的动作加入到程序中呢?这就是我们这次用到的AOP实现的核心技术动态代理(Dynamic Proxy)。具体代码如下:

public class MyProxy  implements InvocationHandler{
private Object targetObject;
public Object createProxyInstance(Object targetObject) {
this.targetObject = targetObject;
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(),
this);
} public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
command();
Object ret = method.invoke(targetObject, args);
award();
return ret;
} private void command() {
System.out.println("驯兽师发出命令!");
} private void award(){
System.out.println("驯兽师给与奖励!");
}
}

上述代码实现完成之后,我们改如何调用呢?参考代码如下:

public class Client {
public static void main(String[] args) {
MyProxy hander = new MyProxy();
Animal dog = (Animal)hander.createProxyInstance(new Dog());
dog.run();
dog.jump();
}
}

执行结果如下:

关于AOP编程的实例演示就完成了,接下来重新回顾一下AOP与OOP的相关概念。

5、AOP与OOP的关系

OOP针对业务处理过程的实体(Dog、Cat、Duck)及其属性和行为(run)进行抽象封装,以获得更加清晰高效的逻辑单元划分。而AOP则是针对业务处理过程中(run或jump)的切面(command和award)进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。这两种设计思想在目标上有着本质的差异。

深入浅出Spring(三)的更多相关文章

  1. [置顶] 深入浅出Spring(三) AOP详解

    上次的博文深入浅出Spring(二) IoC详解中,我为大家简单介绍了一下Spring框架核心内容中的IoC,接下来我们继续讲解另一个核心AOP(Aspect Oriented Programming ...

  2. 深入浅出spring IOC中三种依赖注入方式

    深入浅出spring IOC中三种依赖注入方式 spring的核心思想是IOC和AOP,IOC-控制反转,是一个重要的面向对象编程的法则来消减计算机程序的耦合问题,控制反转一般分为两种类型,依赖注入和 ...

  3. 深入浅出Spring(三) AOP详解

    上次的博文深入浅出Spring(二) IoC详解中,我为大家简单介绍了一下Spring框架核心内容中的IoC,接下来我们继续讲解另一个核心AOP(Aspect Oriented Programming ...

  4. [MVC] 深入浅出Spring MVC

    [MVC] 深入浅出Spring MVC 转:http://4925054.blog.51cto.com/4915054/1176855 Spring MVC主要包括以下要点: 1:由Dispatch ...

  5. 深入浅出Spring(四) Spring实例分析

    上次的博文中 深入浅出Spring(二) IoC详解 和 深入浅出Spring(三) AOP详解中,我们分别介绍了一下Spring框架的两个核心一个是IoC,一个是AOP.接下来我们来做一个Sprin ...

  6. [置顶] 深入浅出Spring(四) Spring实例分析

    上次的博文中 深入浅出Spring(二) IoC详解 和 深入浅出Spring(三) AOP详解中,我们分别介绍了一下Spring框架的两个核心一个是IoC,一个是AOP.接下来我们来做一个Sprin ...

  7. 转:深入浅出spring IOC中四种依赖注入方式

    转:https://blog.csdn.net/u010800201/article/details/72674420 深入浅出spring IOC中四种依赖注入方式 PS:前三种是我转载的,第四种是 ...

  8. 06.深入浅出 Spring Boot - 数据访问之Druid

    代码下载:https://github.com/Jackson0714/study-spring-boot.git 一.Druid是什么? 1.Druid是数据库连接池,功能.性能.扩展性方面都算不错 ...

  9. 07.深入浅出 Spring Boot - 数据访问之Mybatis(附代码下载)

    MyBatis 在Spring Boot应用非常广,非常强大的一个半自动的ORM框架. 代码下载:https://github.com/Jackson0714/study-spring-boot.gi ...

  10. Spring框架系列(4) - 深入浅出Spring核心之面向切面编程(AOP)

    在Spring基础 - Spring简单例子引入Spring的核心中向你展示了AOP的基础含义,同时以此发散了一些AOP相关知识点; 本节将在此基础上进一步解读AOP的含义以及AOP的使用方式.@pd ...

随机推荐

  1. Linux sh脚本用spool导出oracle数据库指定表表数据

    脚本如下,已验证可用,可配合crontab使用. 1 #!/bin/bash cd /opt/oracle/datafor_kf #redirect environment variables sou ...

  2. 【java基础】接口是否能有实现类?

    接口是否能有实现方法 我的回答: 当然可以 java8以后就允许接口有实现方法: default修饰的方法 static修饰的方法 /** * 能用lambda的情况,接口里面只有一个未实现的方法 * ...

  3. List、Set集合系列之剖析HashSet存储原理(HashMap底层)

    目录 List接口 1.1 List接口介绍 1.2 List接口中常用方法 List的子类 2.1 ArrayList集合 2.2 LinkedList集合 Set接口 3.1 Set接口介绍 Se ...

  4. c# 保留两位小数点

    保留两位小数点 由于简单的原因大家直接看代码块. using System; namespace HelloWorld { class Program { static void Main(strin ...

  5. (转载)学校搭建使用nginx同时编译rtmp-module进行直播的技术文档

    原文地址:学校搭建使用 nginx 同时编译 rtmp-module 进行直播的技术文档 转载自我的大佬同学 MetalkgLZH.学校有几次需要全校观看网络直播的情况,但是学校的带宽不允许所有的班一 ...

  6. python实现清屏

    往常都是用os.system("cls")清屏,但是发现每次执行完这个命令后都会出现一个空白字符 尝试了一下午,网上也没解决的办法 最后: os.system("cls& ...

  7. 5. SOFAJRaft源码分析— RheaKV中如何存放数据?

    概述 上一篇讲了RheaKV是如何进行初始化的,因为RheaKV主要是用来做KV存储的,RheaKV读写的是相当的复杂,一起写会篇幅太长,所以这一篇主要来讲一下RheaKV中如何存放数据. 我们这里使 ...

  8. P3052 [USACO12MAR]摩天大楼里的奶牛(迭代加深搜索)

    (已经一句话了) 第一反应:暴力 第二反应:朴素算法过不去 第三反应:没法折半暴搜(没法统计答案) 所以,歪歪了一个类似贪心刷表的方法,过了这道题. 首先,如果爆搜的话会有几个状态: 当前牛 当前几个 ...

  9. Python基本数据结构之集合

    一道python面试的一个小问题,说怎么使用一行代码将一个列表里的重复元素,其实这里只要将列表转换成集合就可以了. 定义 集合跟我们学的列表有点像,也是可以存一堆数据,不过它有几个独特的特点,令其在整 ...

  10. 字符串模拟大数相加——Java实现

    本题是CVTE二面编程题,首先考虑返回值肯定是一个字符串(int会有溢出可能),并且两个字符串只含数字,不含”+“.”-“这种. 代码如下: public static String add(Stri ...