1. 为什么要使用动态代理?

动态代理:在不改变原有代码的情况下上进行对象功能增强 使用代理对象代替原来的对象完成功能 进而达到拓展功能的目的

2.JDK Proxy 动态代理面向接口的动态代理

特点:

  1. 一定要有接口和实现类的存在 代理对象增强的是实现类 在实现接口的方法重写的方法
  2. 生成的代理对象只能转换成 接口的不能转换成 被代理类
  3. 代理对象只能增强接口中定义的方法 实现类中其他和接口无关的方法是无法增强的
  4. 代理对象只能读取到接口中方法上的注解 不能读取到实现类方法上的注解

    使用方法:
public class Test1 {
public static void main(String[] args) {
Dinner dinner=new Person("张三");
// 通过Porxy动态代理获得一个代理对象,在代理对象中,对某个方法进行增强
// ClassLoader loader,被代理的对象的类加载器
ClassLoader classLoader = dinner.getClass().getClassLoader();
// Class<?>[] interfaces,被代理对象所实现的所有接口
Class[] interaces= dinner.getClass().getInterfaces();
// InvocationHandler h,执行处理器对象,专门用于定义增强的规则
InvocationHandler handler = new InvocationHandler(){
// invoke 当我们让代理对象调用任何方法时,都会触发invoke方法的执行
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// Object proxy, 代理对象
// Method method,被代理的方法
// Object[] args,被代理方法运行时的实参
Object res=null;
if(method.getName().equals("eat")){
System.out.println("饭前洗手");
// 让原有的eat的方法去运行
res =method.invoke(dinner, args);
System.out.println("饭后刷碗");
}else{
// 如果是其他方法,那么正常执行就可以了
res =method.invoke(dinner, args);
}
return res;
}
};
Dinner dinnerProxy =(Dinner) Proxy.newProxyInstance(classLoader,interaces,handler);
//dinnerProxy.eat("包子");
dinnerProxy.drink();
}
}
interface Dinner{
void eat(String foodName);
void drink();
}
class Person implements Dinner{
private String name;
public Person(String name) {
this.name = name;
}
@Override
public void eat(String foodName) {
System.out.println(name+"正在吃"+foodName);
}
@Override
public void drink( ) {
System.out.println(name+"正在喝茶");
}
}
class Student implements Dinner{
private String name;
public Student(String name) {
this.name = name;
}
@Override
public void eat(String foodName) {
System.out.println(name+"正在食堂吃"+foodName);
}
@Override
public void drink( ) {
System.out.println(name+"正在喝可乐");
}
}

3.CGlib动态代理

cglib动态代理模式是面向父类

特点:

  1. 面向父类的和接口没有直接关系

    2.不仅可以增强接口中定义的方法还可以增强其他方法

    3.可以读取父类中方法上的所有注解

  2. 使用实例

public class Test1 {
@Test
public void testCglib(){
Person person =new Person();
// 获取一个Person的代理对象
// 1 获得一个Enhancer对象
Enhancer enhancer=new Enhancer();
// 2 设置父类字节码
enhancer.setSuperclass(person.getClass());
// 3 获取MethodIntercepter对象 用于定义增强规则
MethodInterceptor methodInterceptor=new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
/*Object o, 生成之后的代理对象 personProxy
Method method, 父类中原本要执行的方法 Person>>> eat()
Object[] objects, 方法在调用时传入的实参数组
MethodProxy methodProxy 子类中重写父类的方法 personProxy >>> eat()
*/
Object res =null;
if(method.getName().equals("eat")){
// 如果是eat方法 则增强并运行
System.out.println("饭前洗手");
res=methodProxy.invokeSuper(o,objects);
System.out.println("饭后刷碗");
}else{
// 如果是其他方法 不增强运行
res=methodProxy.invokeSuper(o,objects); // 子类对象方法在执行,默认会调用父类对应被重写的方法
}
return res;
}
};
// 4 设置methodInterceptor
enhancer.setCallback(methodInterceptor);
// 5 获得代理对象
Person personProxy = (Person)enhancer.create();
// 6 使用代理对象完成功能
personProxy.eat("包子");
}
}
class Person {
public Person( ) {
}
public void eat(String foodName) {
System.out.println("张三正在吃"+foodName);
}
}

两个动态代理的区别

  1. JDK动态代理是面向接口的,只能增强实现类中接口中存在的方法。CGlib是面向父类的,可以增强父类的所有方法
  2. JDK得到的对象是JDK代理对象实例,而CGlib得到的对象是被代理对象的子类

动态代理jdk的Proxy与spring的CGlib的更多相关文章

  1. 转:JDK动态代理为什么必须用接口以及与CGLIB的对比

    参考链接: JDK动态代理为什么必须用接口以及与CGLIB的对比 文章中提到:试验了JDK动态代理与CGLIB动态代理.从Spring的AOP框架介绍中得知对于使用接口的类,Spring使用JDK动态 ...

  2. 动态代理jdk和cglib的区别

    学习来源贴:http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类, ...

  3. Java事务处理全解析(六)—— 使用动态代理(Dynamic Proxy)完成事务

    在本系列的上一篇文章中,我们讲到了使用Template模式进行事务管理,这固然是一种很好的方法,但是不那么完美的地方在于我们依然需要在service层中编写和事务处理相关的代码,即我们需要在servi ...

  4. spring的AOP动态代理--JDK代理和CGLIB代理区分以及注意事项

    大家都知道AOP使用了代理模式,本文主要介绍两个代理模式怎么设置以及区别,对原文一些内容进行了引用后加入了自己的理解和更深入的阐述:   一.JDK代理和CGLIB代理的底层实现区别* JDK代理只能 ...

  5. Spring -07 -AOP [面向切面编程] - 使用注解@+ AspectJ 方式实现环绕/前/后等通知 -超简洁 --静态代理/动态代理{JDK/cglib}

    1.spring 不会自动去寻找注解,必须告诉 spring 哪些包下的类中可能有注解;使用注解来取代配置文件.1.1 引入xmlns:context ,指定扫描范围 <context:comp ...

  6. 动态代理:JDK原生动态代理(Java Proxy)和CGLIB动态代理原理+附静态态代理

    本文只是对原文的梳理总结,以及自行理解.自己总结的比较简单,而且不深入,不如直接看原文.不过自己梳理一遍更有助于理解. 详细可参考原文:http://www.cnblogs.com/Carpenter ...

  7. 代理模式(Proxy)--动态代理(JDK)

    在是上一篇博客中实现了静态代理. 在上篇的结尾提到了一个问题: 思考:如果我们下需要对火车,自行车实现相同的代理,我们又该如何实现呢? 这篇博客就来解决这个问题: 解决这类问题需要用到动态代理技术,实 ...

  8. 探索Mybatis之JDK动态代理:探究Proxy.newProxyInstance()生成的代理类解析

    Mybatis的Mapper接口UserMapper 1 package com.safin.Mapper; 2 3 import com.safin.Pojo.User; 4 5 import ja ...

  9. 动态代理:jdk动态代理和cglib动态代理

    /** * 动态代理类:先参考代理模式随笔,了解代理模式的概念,分为jdk动态代理和cglib,jdk动态代理是通过实现接口的方式创建代理类的,cglib是通过继承类的方式实现的代理类的 * jdk动 ...

随机推荐

  1. 分布式系统一致性算法(Raft)

    过去, Paxos一直是分布式协议的标准,但是Paxos难于理解,更难以实现,Google的分布式锁系统Chubby作为Paxos实现曾经遭遇到很多坑. 来自Stanford的新的分布式协议研究称为R ...

  2. 大型网站高可用架构之CAP原理

    在讨论高可用数据服务架构之前,必须先讨论的一个话题是,为了保证数据的高可用,网站通常会牺牲另一个也很重要的指标:数据一致性. CAP原理认为,一个提供数据服务的存储系统无法同时满足数据一致性.数据可用 ...

  3. vue+uniapp实现多任务并发下载文件 | 断点续下, 任务列表, 多任务并发限制

    一.插件简介 zhimi-downloadManager(智密 - 多任务下载管理插件)是一个支持多任务多并发下载,支持多/单任务管理,并且实时反馈任务下载进度的uniapp原生插件.平台支持:And ...

  4. 在制造业的工业2.0中应用MOM系统

    介绍 什么是制造运营管理 (MOM) 系统和 IT 架构的最佳实践? 行业专家对制造类型和供应网络有何建议? 管理思维和企业文化是否因不断变化的全球市场而过时? MOM 技术是否过于昂贵,IT 架构是 ...

  5. 网络编程之UDP(2)linux查看socket默认缓冲区大小和最大值

    默认值 命令: cat /proc/sys/net/core/rmem_default 结果: 最大值 命令: cat /proc/sys/net/core/rmem_max 结果:

  6. 【LeetCode】292. Nim Game 解题报告(Java & Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  7. 【LeetCode】405. Convert a Number to Hexadecimal 解题报告(Java & Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 Java解法 Python解法 日期 题目地址:ht ...

  8. 【LeetCode】380. Insert Delete GetRandom O(1) 解题报告(Python)

    [LeetCode]380. Insert Delete GetRandom O(1) 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxu ...

  9. 【LeetCode】819. Most Common Word 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 正则+统计 日期 题目地址:https://leet ...

  10. Docker 与 K8S学习笔记(七)—— 容器的网络

    本节我们来看看Docker网络,我们这里主要讨论单机docker上的网络.当docker安装后,会自动在服务器中创建三种网络:none.host和bridge,接下来我们分别了解下这三种网络: $ s ...