AOP是指面向切面编程。

在学习AOP之前先来了解一下代理,因为传说中的AOP其实也对代理的一种应用。

首先来看这样一段代码:

public interface Hello {void say(String name);
}

实现类:

public class HelloImpl implements Hello {public void say(String name) {System.out.println("Hello!"+name);}
}

如果现在需要在say调用的前后做一些操作,那最简单的方法就是直接在say方面中增加代码,但这样肯定不够优雅。

这时候可以用第一种代理模式:静态代理

public class HelloProxy implements Hello {private Hello hello;public HelloProxy(){hello=new HelloImpl();}public void say(String name) {before();hello.say(name);after();}private void before(){System.out.println("before");}private void after(){System.out.println("after");}
}

这样我们在保留原来HelloImple中say方法的同时,用HelloProxy代理在say方法的前后增加了before和after

调用一下试试:

 public static void main(String[] args){Hello helloProxy=new HelloProxy();helloProxy.say("Gary");
}

运行结果:

那么新的问题来了,如果每次都需要写一个代理类不也很麻烦吗,项目中就会有很多个xxxProxy,因此就出现了 JDK动态代理

代码如下:

public class DynamicProxy implements InvocationHandler {private Object target;public DynamicProxy(Object target){this.target=target;}public <T> T getProxy(){return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {before();Object result=method.invoke(target,args);after();return result;}private void before(){System.out.println("before");}private void after(){System.out.println("after");}
}

注:Proxy.newProxyInstance()参数有三个:

  • ClassLoader
  • 该实现类的所有接口
  • 动态代理对象

在该类中target就是被代理的对象,该类实现了InvocationHandler接口,通过反射去动态创建Hello接口的代理类

那么现在的调用就变简单了:

 public static void main(String[] args){DynamicProxy dynamicProxy=new DynamicProxy(new HelloImpl());Hello helloProxy= dynamicProxy.getProxy();helloProxy.say("gary");}

用了JDK动态代理后,我们觉得还是有问题,如果要代理一个没有接口的类,该怎么办呢,于是就轮到我们的 CGlib动态代理 出场了。

在Spring、Hibernate等框架中都用到了CGlib动态代理,maven资源如下:

 <!-- https://mvnrepository.com/artifact/cglib/cglib --><dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.2.6</version></dependency>

他的使用需要实现MethodInterceptor类,并完成intercept方法。CGlib 提供的是方法级别的代理:

public class CGLibProxy implements MethodInterceptor {public <T> T getProxy(Class<T> cls){return (T) Enhancer.create(cls,this);}public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {before();Object result=methodProxy.invokeSuper(o,objects);after();return result;}private void before(){System.out.println("before");}private void after(){System.out.println("after");}
}

这样使用时就不需要提供接口了:

  public static void main(String[] args){CGLibProxy cgLibProxy= new CGLibProxy();Hello hello=cgLibProxy.getProxy(HelloImpl.class);hello.say("Gary");}

最后再改造一下,加上单例模式就更完美了

    private static CGLibProxy instance=new CGLibProxy();private CGLibProxy(){}public static CGLibProxy getInstance(){return instance;}

调用就改为:

public static void main(String[] args){Hello hello=CGLibProxy.getInstance().getProxy(HelloImpl.class);hello.say("Gary");}

转载于:https://www.cnblogs.com/GuoJunwen/p/9008610.html

springAOP之代理相关推荐

  1. SpringAOP之代理模式

    SpringAOP之代理模式 SpringAOP之代理模式 一.代理模式 二.静态代理 三.JDK动态代理 四.CGLib动态代理 五.总结 SpringAOP之代理模式 SpringAOP指的是在s ...

  2. SpringAOP静态代理和动态代理

    代理模式应用于SpringAOP. SpringAOP.即面向切面的编程范式.多用于权限控制,异常处理,日志管理等场景.主要作用是分离功能性需求和非功能性需求,减少代码冗余.我们在使用的时候可以集中处 ...

  3. Java Spring-AOP动态代理-JDK和CGlib实现

    Java Spring-AOP CGlib和JDK动态代理实现 编码是为了解决生活中的问题,譬如现在我想用筷子吃饭的时候看手机,那么首先会有两个对象. 现在如果是面向对象编程思想,我们会new一个筷子 ...

  4. Spring-AOP动态代理技术(底层代码)

    1.JDK代理:基于接口的动态代理技术 目标对象必须有接口,目标对象有什么方法,目标接口就有什么方法, 运行期间基于接口动态生成代理对象,所以代理对象也就有目标对象同样的方法. 注意:以下代码只是底层 ...

  5. SpringAOP之代理设计模式

    [1]设计模式: 概念: 设计模式其实就是代码的一种结构的设计思路. 好处: 增加代码健壮性 易修改性 可扩展性 设计模式的种类: 三大种类: 建造类设计模式 结构类设计模式 行为类设计模式 参考网址 ...

  6. SpringAop动态代理的两种实现方式

    Spring的面向切面编程也是基于动态代理来实现的 静态代理:也就是自己手动创建的代理对象 动态代理:也就是在程序运行中通过配置参生的 那么Spring的AOP也就是面向切面编程,就是基于动态代理来实 ...

  7. SpringAOP之代理模式选择

    目标类:ProxyFactoryBean 目标方法: public Object getObject() throws BeansException {initializeAdvisorChain() ...

  8. SpringAOP JDK动态代理

    1.本篇博客的背景和目的 目前我本人正在学习SpringFramework的知识,这也是这个专栏的主题.我前面的几篇博文中,简单的认识了一下SpringFramework,记录了SpringFrame ...

  9. spring AOP原理分析:静态代理;JDK实现接口动态代理;Cglib继承父类代理;SpringAop的责任链模式调用

    普通静态代理 代理类和真实类都需要实现同一个接口 接口 package com.fchan.layui.represent.service; /*** 静态代理demo*/ public interf ...

最新文章

  1. pandas索引复合索引dataframe数据、索引dataframe中指定行和指定列交叉格子的数据内容(getting a specific value)、使用元组tuple表达复合索引的指定行
  2. 企业桌面安全管理解决方案
  3. 关于 quick-cocos 状态机
  4. UVA10943简单递推
  5. 可怕的乖孩子_小说《可怕的乖孩子》讲了一个什么故事?
  6. struts2的namespace的问题
  7. 嵌入式常见笔试题总结(3)
  8. 练习算法之前必须了解的多件事
  9. spring boot +vue用什么记录登录状态_为什么很多Spring Boot开发者放弃了Tomcat
  10. matlab的三维数组(三维矩阵)
  11. MySQL group by语句用法
  12. 不拆机更换HG255D的U-BOOT并刷OPENWRT
  13. 利用python爬取飞猪信息_飞猪爬虫项目
  14. sfm支持Linux和Windows吗,VisualSFM的使用方法
  15. 写给新手看的机器学习原理--基于机器翻译
  16. Golang 协程 跟Java NIO
  17. 74CMS模版注入漏洞复现
  18. 企业微信应用分享(一)
  19. python小白进阶之路三——七段数码管的绘制+做一个酷炫的倒计时(函数的复用)
  20. 硬盘IDE、SATA、AHCI模式的区别

热门文章

  1. 使用Service Installer在.NET Core中配置依赖注入而无需任何代码
  2. 小米开源 Redmi K30 Pro 内核源码
  3. php注入类,简单实用的PHP防注入类实例_PHP
  4. bootstrap表单拖拽生成器插件_web前端常用插件、工具类库汇总,新手必收藏!!!...
  5. python ray分布式_分布式框架Ray及RLlib简易理解
  6. Ionic4 Camera插件在iOS13上选取视频失败 上传时候提示权限不足
  7. mac上的Android虚拟机,android虚拟机能在retina MacBook pro上跑吗?
  8. JavaScript 、if else语句判断 、jQurey表单事件
  9. macmini作为远程服务器,如何使用Macbook Pro远程免密码登录Mac mini
  10. 单片机广告灯实验总结_温州很强的ly51s单片机程序开发公司