需求:增强未知方法的代码

简单方案:继承或者聚合

  1. 继承,调用方法前后加增强逻辑

  2. 聚合 - 静态代理

    1. 持有被代理类对象 或者接口

    2. 可通过嵌套实现代理的组合 和 装饰器模式很像

高级方案

  • 代理所有的类,不只是某一类的接口,静态的聚合方式成员属性是具体的
JDK 动态代理
package club.interview.design_pattern.chapt6_proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; /**
* @author QuCheng on 2020/6/15.
*/
public interface Vegetable { void growUp(); class Cabbage implements Vegetable { @Override
public void growUp() {
System.out.println("卷心菜慢慢长大");
}
} class LogProxy implements InvocationHandler { Object o; public LogProxy(Object o) {
this.o = o;
} public static Object getProxy(Object object) {
System.getProperties().setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
return Proxy.newProxyInstance(object.getClass().getClassLoader(),
object.getClass().getInterfaces(), new LogProxy(object));
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("good goods study");
Object invoke = method.invoke(o, args);
System.out.println("day day up");
return invoke;
} public static void main(String[] args) {
Vegetable v = (Vegetable) LogProxy.getProxy(new Cabbage());
v.growUp();
}
} } 
  • proxy源码解读

    • 实际产生的对象是$Proxy0.class的对象,继承proxy,实现目标接口方法
    • 执行目标接口时实际调用super也就是proxy的InvokationHandler的invoke对象
  • 生成代理源码解读Proxy.newInstance(...)
    • 跟进去会发现底层是利用asm动态生成二进制文件$Proxy0.class
Cglib
package club.interview.design_pattern.chapt6_proxy;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
* @author QuCheng on 2020/6/15.
*/
public class CabbageCglib {

public void growUp() {
System.out.println("卷心菜慢慢长大");
}

static class LogProxyCglib implements MethodInterceptor {

@SuppressWarnings("unchecked")
static <T> T getProxy(T o) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(o.getClass());
enhancer.setCallback(new LogProxyCglib());
return (T) enhancer.create();
}

@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("good good study");
// invokeSuper not invoke
Object invoke = methodProxy.invokeSuper(o, objects);
System.out.println("day day up");
return invoke;
}
}

public static void main(String[] args) {

CabbageCglib cabbageCglib = LogProxyCglib.getProxy(new CabbageCglib());
cabbageCglib.growUp();
}
}
两种动态代理对比
  • jdk

    • 优点:jdk原生,可代理有接口实现的类

    • 缺点:代理类必须实现接口

  • cglib

    • 优点:

      • 被代理类无需实现接口

      • 实现简单,无需聚合

    • 缺点:因为是采用继承,被代理类不能被final修饰

【DP-动态代理】JDK&Cglib的更多相关文章

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

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

  2. AOP学习心得&jdk动态代理与cglib比较

    什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP引入 ...

  3. Spring AOP详解 、 JDK动态代理、CGLib动态代理

    AOP是Aspect Oriented Programing的简称,面向切面编程.AOP适合于那些具有横切逻辑的应用:如性能监测,访问控制,事务管理以及日志记录.AOP将这些分散在各个业务逻辑中的代码 ...

  4. 【转载】Spring AOP详解 、 JDK动态代理、CGLib动态代理

    Spring AOP详解 . JDK动态代理.CGLib动态代理  原文地址:https://www.cnblogs.com/kukudelaomao/p/5897893.html AOP是Aspec ...

  5. 017 Java中的静态代理、JDK动态代理、cglib动态代理

    一.静态代理 代理模式是常用设计模式的一种,我们在软件设计时常用的代理一般是指静态代理,也就是在代码中显式指定的代理. 静态代理由业务实现类.业务代理类两部分组成.业务实现类负责实现主要的业务方法,业 ...

  6. JDK动态代理与CGLib动态代理相关问题

    导读: 1.JDK动态代理原理是什么?为什么不支持类的代理? 2.JDK动态代理实例 3.CGLib代理原理是什么? 4.CGLib代理实例 5.JDK动态代理与CGLib代理的区别是什么? 6.总结 ...

  7. Java之代理(jdk静态代理,jdk动态代理,cglib动态代理,aop,aspectj)

    一.概念 代理是什么呢?举个例子,一个公司是卖摄像头的,但公司不直接跟用户打交道,而是通过代理商跟用户打交道.如果:公司接口中有一个卖产品的方法,那么公司需要实现这个方法,而代理商也必须实现这个方法. ...

  8. 动态代理 JDK动态代理 CGLIB代理

    代理模式:代理类和被代理类实现共同的接口(或继承),代理类中存有指向被代理类的索引,实际执行时通过调用代理类的方法.实际执行的是被代理类的方法. 而AOP,是通过动态代理实现的. 一.简单来说: JD ...

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

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

  10. JDK动态代理、CGLib动态代理

    JDK动态代理源码 一.public static Object newProxyInstance ——> 调用下面这个方法二.Class<?> cl = getProxyClass ...

随机推荐

  1. angularjs 指令传参规则

    angularjs 指令传参规则 xx-,data- 驼峰

  2. ZooKeeper未授权漏洞

    ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,它是集群的管理者,监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理操作.最终, ...

  3. spring框架中三层架构相关的注解

    做了这么多年的C++,再去学Java,确实发现,语言都是相通的,即使是Java的那么多生态,理解起来也并不费劲 Spring 框架目前还在学习中,处于 Tourist 阶段,目前只求会做,不求原理,等 ...

  4. 50个SQL语句(MySQL版) 问题八

    --------------------------表结构-------------------------- student(StuId,StuName,StuAge,StuSex) 学生表 tea ...

  5. docker环境下的Grafana安装

    一.参考资源:https://grafana.com/docs/grafana/latest/installation/docker/ 二.过程 1.安装grafana 查看可用image [root ...

  6. jchdl - RTL实例 - Counter4

    https://mp.weixin.qq.com/s/xtvMj5f-Uvx3vesVnH0P_A   计数器.   参考链接 https://github.com/wjcdx/jchdl/blob/ ...

  7. Java实现 蓝桥杯VIP 算法训练 接水问题

    题目描述 有n个人在一个水龙头前排队接水,假如每个人接水的时间为Ti,请编程找出这n个人排队的一种顺序,使得n个人的平均等待时间最小. 输入输出格式 输入格式: 输入文件共两行,第一行为n:第二行分别 ...

  8. Java实现 蓝桥杯VIP 算法提高 连接乘积

    算法提高 连接乘积 时间限制:1.0s 内存限制:256.0MB 问题描述 192这个数很厉害,用它分别乘以1.2.3,会得到: 192 x 1 = 192 192 x 2 = 384 192 x 3 ...

  9. java实现第四届蓝桥杯连号区间数

    连号区间数 题目描述 小明这些天一直在思考这样一个奇怪而有趣的问题: 在1~N的某个全排列中有多少个连号区间呢?这里所说的连号区间的定义是: 如果区间[L, R] 里的所有元素(即此排列的第L个到第R ...

  10. Linux 权限管理-ACL权限

    ACL权限是为了在现有的所有者.所属组.其他人不够使用的情况下使用的,使用它必须保证文件所在的分区支持ACL df -h:查看系统所有分区信息 dumpe2fs -h /dev/vda1,可以查看分区 ...