1.什么是AOP

AOP的全称是Aspect-Oriented Programming,即面向切面编程(也称面向方面编程)。它是面向对象编程(OOP)的一种补充,目前已成为一种比较成熟的编程方式。

在传统的业务处理代码中,通常都会进行事务处理、日志记录等操作。虽然使用OOP可以通过组合或者继承的方式来达到代码的重用,但如果要实现某个功能(如日志记录),同样的代码仍然会分散到各个方法中。这样,如果想要关闭某个功能,或者对其进行修改,就必须要修改所有的相关方法。这不但增加了开发人员的工作量,而且提高了代码的出错率。

为了解决这一问题,AOP思想随之产生。AOP采取横向抽取机制,将分散在各个方法中的重复代码提取出来,然后在程序编译或运行时,再将这些提取出来的代码应用到需要执行的地方。这种采用横向抽取机制的方式,采用传统的OOP思想显然是无法办到的,因为OOP只能实现父子关系的纵向的重用。虽然AOP是一种新的编程思想,但却不是OOP的替代品,它只是OOP的延伸和补充。

而Spring中的AOP是基于动态代理实现的,即 JDK动态代理和Cglib动态代理。

2.JDK动态代理

JDK动态代理是java.lang.reflect.*包提供的方式,它必须借助一个接口才能产生代理对象,所以在使用代理之前,先要有一个接口,然后定义一个类实现接口。

2.1 定义接口

interface HelloWorld {void sayHelloWorld();void sayGoodBye();
}

2.2 实现接口

class HelloWorldImpl implements HelloWorld {@Overridepublic void sayHelloWorld() {// TODO Auto-generated method stubSystem.out.println("Hello World");}@Overridepublic void sayGoodBye() {// TODO Auto-generated method stubSystem.out.println("GoodBye");}
}

2.3 动态代理绑定和代理逻辑实现

public class Demo01_Proxy implements InvocationHandler {//真实对象private Object target = null;/*** 建立代理对象和真实对象的代理关系,并返回代理对象*/public Object bind(Object target) {this.target = target;return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);}/*** 代理方法逻辑*  porxy 代理对象*  method 当前调度方法*  args 当前方法参数*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("进入代理逻辑方法");System.out.println("在调度真实对象之前的服务");Object obj = method.invoke(target, args); //相当于调用sayHelloWorld方法System.out.println("在调度真实对象之后的服务");return obj;}/***测试代码*/@Testpublic void testJdkProxy() {Demo01_Proxy jdk = new Demo01_Proxy();//绑定关系,因为挂在HelloWorld接口下,所有声明代理对象HelloWorld proxyHelloWorld proxy = (HelloWorld) jdk.bind(new HelloWorldImpl());//注意,此时proxy已经是代理对象,他会进入代理的逻辑方法invoke中proxy.sayGoodBye();}}

实现过程:第一步,建立代理对象和真实对象的关系,这里使用了bind方法去完成,方法中首先用类的属性target保存了真实对象,然后通过如下代码建立并生成代理对象并返回。

Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);

第二步,实现代理逻辑方法,invoke方法可以实现代理逻辑,当我们使用了代理对象调度方法后,它就会进入invoke方法里面。即测试代码的proxy.sayGoodBye();执行就会进入invoke方法中,实现在调用实现类的每个方法之前和之后都加上的相关操作,实现AOP思想。

3.CGLIB动态代理

JDK动态代理必须实现接口才能使用,在一些不能提供接口的环境中,只能采用其他第三方技术,即CGLIB动态代理,它的优势在于不用提供接口,只要一个非抽象类就可以实现动态代理。

3.1 定义一个类

/*** 被代理对象* @author Administrator**/
class Reflect {public void print(String name) {System.out.println("hello" + name);}
}

3.2 编写动态代理代码

public class Demo02_Proxy implements MethodInterceptor {/*** 生成Cglib代理对象* @param cls* @return*/public Object getProxy(Class cls) {//enhancer 增强类对象Enhancer enhancer = new Enhancer();//设置增强类型enhancer.setSuperclass(cls);//定义代理逻辑对象为当前对象,要求当前对象实现MethodInterceptor方法enhancer.setCallback(this);//生成并返回代理对象return enhancer.create();}/*** 代理逻辑方法* @param proxy 代理对象* @param method 方法* @param args 方法参数* @param methodProxy 方法代理* @return 代理逻辑返回* @throws Throwable*/@Overridepublic Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {System.out.println("调用真实对象前");Object result = methodProxy.invokeSuper(proxy, args);System.out.println("调用真实对象后");return result;}/***测试代码*/@Testpublic void testCglibProxy() {Demo02_Proxy proxy = new Demo02_Proxy();Reflect reflect = (Reflect) proxy.getProxy(Reflect.class);reflect.print("张三");}
}

这里使用了CGLIB的加强者Enhancer,通过设置超类的方法(setSuperClass),然后通过setCallback方法设置哪个类为它的代理类。其中,参数this就意味着当前对象,那就要求用this这个对象实现接口MethodInterceptor的方法-intercept,然后返回代理对象。那么此时当前类中的intercept方法就是其代理逻辑方法,在真实对象方法气候进行打印,是通过如下代码实现。

Object result = methodProxy.invoke(proxy, args);

最后关于Cglib导包问题做一下简述:asm.jar,cglib-2.1.3.jar(两包即可)

AOP和动态代理之间的关系相关推荐

  1. AOP、动态代理、CGlib(原理实践)

    Java 代理模式实现方式,主要有如下五种方法: 1. 静态代理,工程师编辑代理类代码,实现代理模式:在编译期就生成了代理类. 2. 基于 JDK 实现动态代理,通过jdk提供的工具方法Proxy.n ...

  2. Spring 初识Aop JDK动态代理实现 原理初显

    Spring 初识Aop JDK动态代理实现 原理初显 一.项目结构 二.具体步骤: 1.创建maven项目 创建好包结构 2.写一个TestDao接口 及实现类 3. 写一个自己的切面类 4.jav ...

  3. spring—AOP 的动态代理技术

    AOP 的动态代理技术 常用的动态代理技术 JDK 代理 : 基于接口的动态代理技术 cglib 代理:基于父类的动态代理技术 JDK 代理 public class proxy {@Testpubl ...

  4. Spring : Spring Aop CGLIB动态代理调用过程

    1.美图 2.概述 CGLIB动态代理参考: CGLIB动态代理 CGLIB原理解析参考:CGLIB原理解析 3.分析 Spring AOP CGLIB动态代理调用过程分析,CGLIB动态代理调用过程 ...

  5. spring 的AOP和动态代理分析

    spring的AOP到底是什么呢? 看看百度怎么说 AOP(Aspect Oriented Programming 面向切面编程),通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AO ...

  6. spring的aop的动态代理机制都有哪些_Spring学习(4):Spring AOP

    Spring AOP说明 AOP(Aspect Oriented Pragraming)面向切面编程,AOP采用横向抽取机制,取代了传统纵向继承体系的重复性代码(性能监视.事务管理.安全检查.缓存). ...

  7. spring面向AOP之动态代理

    动态代理中有两个重要的接口,一个是InvocationHandle,另一个是Proxy. 分别来说明这两个接口的作用吧! InvocationHandle接口' java.lang.reflect.I ...

  8. AOP jdk动态代理

    一: jdk动态代理是Spring AOP默认的代理方法.要求 被代理类要实现接口,只有接口里的方法才能被代理,主要步骤是先创建接口,接口里创建要被代理的方法,然后定义一个实现类实现该接口,接着将被代 ...

  9. SpringBoot/Spring AOP默认动态代理方式

    Spring 5.x中AOP默认依旧使用JDK动态代理 SpringBoot 2.x开始,AOP为了解决使用JDK动态代理可能导致的类型转换异常,而使用CGLIB. 在SpringBoot 2.x中, ...

最新文章

  1. python随机数生成_关于Python中的随机数生成步骤和随机数质量
  2. [数据库] SQL语句select简单记录总结
  3. mysql ddl dql_MySQL的DDL和DML及其DQL数据库操作
  4. 我对 OneData 数据中台体系架构的一些思考
  5. Windows WSL Ubuntu下配置JDK环境变量
  6. mysq 没有mysql数据库_mysq 没有mysql数据库
  7. 常见springboot依赖包关系
  8. 【hibernate】idea利用maven搭建hibernate环境(创建hibernate配置文件(包括cfg和hbm))
  9. 6 DHCPV6原理
  10. FlashFXP连接失败(连接已拒绝)及530 permission denied(连接已被客户端关闭)
  11. Reinforcement Learning An Introduction~The 10-armed Testbed
  12. pytorch 计算模型的GFlops和total params的方法
  13. json转xml报[java.lang.NoClassDefFoundError: nu/xom/Serializer]
  14. kanzi案例Coin
  15. 80后发财靠康波:周金涛生前20篇雄文精华,一文尽览
  16. paddleHub(一)使用预训练模型推理
  17. 字符串流stringstream(头文件sstream)
  18. 癌细胞自噬调控肿瘤发生与发展的研究进展(2021年5月)
  19. [转载]我们为什么不能虐待动物
  20. moment常用用法详解

热门文章

  1. Zipline Beginner Tutorial
  2. Zipline学习笔记
  3. 《微信小程序案例2》如何动态给css样式增加或删除class类
  4. shell教程(脚本 运行 传递 )
  5. 【Tool】如何使用 Uniflash 烧写 WIFI 芯片 CC3200
  6. css-全屏背景图片
  7. 她说:千万别学Python!80%的程序员炸了:请正面刚!
  8. 802.1x认证方式(EAP中继认证与EAP终结认证)
  9. linux xargs cp,Linux xargs命令的使用
  10. 企业家--必读的 7 本伟大商业书籍