代理模式 
        代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。

按照代理的创建时期,代理类可以分为两种:
静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。
动态代理:在程序运行时,运用反射机制动态创建而成。

在JDK 1.3以后提供了动态代理的技术,允许开发者在运行期创建接口的代理实例。 JDK的动态代理主要涉及到java.lang.reflect包中的两个类:Proxy和InvocationHandler。其中InvocationHandler是一个接口,可以通过实现该接口定义横切逻辑,在并通过反射机制调用目标类的代码,动态将横切逻辑和业务逻辑编织在一起。

一、静态代理
1. 接口类:Count.java

public interface Count {     // 查看账户方法     public void queryCount();     // 修改账户方法     public void updateCount();
}

2. 实现类:CountImpl.java

public class CountImpl implements Count {@Overridepublic void queryCount() {System.out.println("查看账户方法...");}@Overridepublic void updateCount() {System.out.println("修改账户方法...");}
}

3. 代理类:CountProxy.java

public class CountProxy implements Count {     private CountImpl countImpl;     /**   * 覆盖默认构造器   * @param countImpl   */     public CountProxy(CountImpl countImpl) {     this.countImpl = countImpl;     }     @Override     public void queryCount() {     System.out.println("事务处理之前");     // 调用委托类的方法;
        countImpl.queryCount();     System.out.println("事务处理之后");     }     @Override     public void updateCount() {     System.out.println("事务处理之前");     // 调用委托类的方法;
        countImpl.updateCount();     System.out.println("事务处理之后");     }
}

4. 测试类:TestCount.java

public class TestCount {public static void main(String[] args) {CountImpl countImpl = new CountImpl();CountProxy countProxy = new CountProxy(countImpl);countProxy.updateCount();countProxy.queryCount();}
}

观察代码可以发现每一个代理类只能为一个接口服务,这样一来程序开发中必然会产生过多的代理,而且,所有的代理操作除了调用的方法不一样之外,其他的操作都一样,则此时肯定是重复代码。解决这一问题最好的做法是可以通过一个代理类完成全部的代理功能,那么此时就必须使用动态代理完成。

二、动态代理

1. 接口类:

public interface PersonService {public String getPersonName(Integer personId);public void save(String name);public void update(Integer personId, String name);
}

2. 实现类:

public class PersonServiceBean implements PersonService {public String user = null;public PersonServiceBean(){};public PersonServiceBean(String user){this.user = user;}@Overridepublic String getPersonName(Integer personId) {System.out.println("这是find方法");return this.user;}@Overridepublic void save(String name) {System.out.println("这是save方法");}@Overridepublic void update(Integer personId, String name) {System.out.println("这是update方法");}public String getUser() {return user;}public void setUser(String user) {this.user = user;}
}

3. JDK动态代理代理类:

/** * 切面   */
public class JDKProxyFactory implements InvocationHandler{  private Object proxyObject; //目标对象  /** * 绑定委托对象并返回一个代理类  * @param proxyObject * @return */  public Object createProxyInstance(Object proxyObject) {this.proxyObject = proxyObject;//生成代理类的字节码加载器 ClassLoader classLoader = proxyObject.getClass().getClassLoader();//需要代理的接口,被代理类实现的多个接口都必须在这里定义  (这是一个缺陷,cglib弥补了这一缺陷)    Class<?>[] proxyInterface = proxyObject.getClass().getInterfaces();//织入器,织入代码并生成代理类return Proxy.newProxyInstance(classLoader, proxyInterface, this);}@Override  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  Object result = null;//控制哪些用户执行切入逻辑if(bean.getUser() != null) {//执行原有逻辑result = method.invoke(this.proxyObject, args);}return result;  }
}

4. 测试类:

public class AopTest {@Testpublic void proxyTest()  {JDKProxyFactory jpf = new JDKProxyFactory();PersonServiceBean personService = (PersonServiceBean) jpf.createProxyInstance(new PersonServiceBean("XXX"));personService.save("888");}
}

上面是提供了用户名的,所以终端会打印出”我是save()方法“,然后我们将 Java代码

PersonServiceBean personService = (PersonServiceBean)jpf.createProxyInstance(new PersonServiceBean("XXX"));  
改为不提供用户名,即
PersonServiceBean personService = (PersonServiceBean) jpf.createProxyInstance(new PersonServiceBean());  

这时候在允许代码发现终端不打印出"我是save()方法",证明我们的动态代理是成功的。

转载于:https://www.cnblogs.com/atai/p/8601853.html

[转]JDK动态代理相关推荐

  1. (转)面试必备技能:JDK动态代理给Spring事务埋下的坑!

    一.场景分析 最近做项目遇到了一个很奇怪的问题,大致的业务场景是这样的:我们首先设定两个事务,事务parent和事务child,在Controller里边同时调用这两个方法,示例代码如下: 1.场景A ...

  2. 【spring】初识aop(面向切面编程) 使用jdk动态代理

    BankServiceIImple.java 代码实现: package com.zzxtit.aop;import java.math.BigDecimal;public interface Ban ...

  3. 【原创】分布式之缓存击穿 【原创】自己动手实现静态资源服务器 【原创】自己动手实现JDK动态代理...

    [原创]分布式之缓存击穿 什么是缓存击穿 在谈论缓存击穿之前,我们先来回忆下从缓存中加载数据的逻辑,如下图所示 因此,如果黑客每次故意查询一个在缓存内必然不存在的数据,导致每次请求都要去存储层去查询, ...

  4. 【干货】JDK动态代理的实现原理以及如何手写一个JDK动态代理

    动态代理 代理模式是设计模式中非常重要的一种类型,而设计模式又是编程中非常重要的知识点,特别是在业务系统的重构中,更是有举足轻重的地位.代理模式从类型上来说,可以分为静态代理和动态代理两种类型. 在解 ...

  5. aop的四种增强以及JDK动态代理、Cglib动态代理

    动态代理 AOP底层实现:有接口自动应用的就是JDK动态代理 (1).JDK 在运行时运行时注入 本质:在内存中构建出接口的实现类 特点:被代理对象,必须有接口 实例: import java.lan ...

  6. JDK动态代理小例子

    一个小汽车,有一个跑run()的方法,我们想使用jdk动态代理使小汽车执行run之前 加点油,run之后洗车. 有四个类,接口Car(小汽车)Kayan(具体实现类(卡宴)) CarProxy(汽车的 ...

  7. jdk动态代理实例和cglib动态代理实例_CGLib 动态代理 原理解析

    JDK 动态代理实现与原理 首先来看一段CGLib代理的测试代码(MethodInterceptor的测试, 其他类型这里不做展开了). Util类的代码在后面给出的码云片段中 public 下面的输 ...

  8. java jdk动态代理学习记录

    转载自: https://www.jianshu.com/p/3616c70cb37b JDK自带的动态代理主要是指,实现了InvocationHandler接口的类,会继承一个invoke方法,通过 ...

  9. 利用JDK动态代理机制实现简单拦截器

    利用JDK动态代理机制实现简单的多层拦截器 首先JDK动态代理是基于接口实现的,所以我们先定义一个接口 public interface Executer {public Object execute ...

  10. JDK动态代理实现原理--转载

    之前虽然会用JDK的动态代理,但是有些问题却一直没有搞明白.比如说:InvocationHandler的invoke方法是由谁来调用的,代理对象是怎么生成的,直到前几个星期才把这些问题全部搞明白了.  ...

最新文章

  1. i=1,为什么 (++i)+(++i)=6?
  2. web浏览器进化简史
  3. 点阵字体显示系列之三:使用ncurses显示汉字
  4. 微软推出一波AI新功能:自动生成图表、更贴心的Cortana和搜索
  5. Matlab 四阶龙格库塔法求解二元常微分方程组
  6. cbnertvirtual内部框架下载_关于matepad pro谷歌框架
  7. Radius 协议介绍
  8. linux服务器安装cuda,在Linux下安装Cuda5
  9. Ego-planner安装
  10. 扫描仪扫描器的功用和原理
  11. stm32定时器的ETR、CH1N、CH2N、CH3N
  12. 谭谭牛顿的牛眼之人眼是红外线成像仪谭
  13. C:/Inetpub/AdminsScripts的常用语法
  14. thawte,globalsign,alphassl,rapidssl,geotrust,digicert证书品牌的对照
  15. 使用 hugo 快速开发博客网页
  16. RTC编程挑战赛 开源项目推荐
  17. Proguard的介绍
  18. Mathematica中的常用基本操作
  19. Word文件的编辑密码忘记了怎么办?
  20. TFX发展简史/《Towards ML Engineering: A Brief History Of TensorFlow Extended (TFX)》

热门文章

  1. 用matlab找出所有真因子,在matlab中找出与fmincon匹配两条曲线的缩放因子
  2. 玩转算法面试:(一)什么是算法面试?
  3. 汉诺塔(三) 判断操作是否合法 + 栈(stack)数组
  4. sql语句延时执行或者是指定时间执行
  5. axis1 c# 接口 调用_java axis 调用C# webService的例子
  6. mysql text转varchar_关于企业面试中:“ Mysql重点 ”的28道面试题解析!
  7. 阻止form表单提交的常用方式
  8. 钢铁侠头盔制作图纸下载_如何在10分钟内制作头盔图
  9. windows安装gnu_在Windows上安装GNU Emacs
  10. linux重置root密码_重置丢失的Linux root密码,错误密码的历史记录,Python,Ruby,课堂解决方案等