【DP-动态代理】JDK&Cglib
需求:增强未知方法的代码
简单方案:继承或者聚合
继承,调用方法前后加增强逻辑
聚合 - 静态代理
持有被代理类对象 或者接口
可通过嵌套实现代理的组合 和 装饰器模式很像
高级方案
- 代理所有的类,不只是某一类的接口,静态的聚合方式成员属性是具体的
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的更多相关文章
- Spring -07 -AOP [面向切面编程] - 使用注解@+ AspectJ 方式实现环绕/前/后等通知 -超简洁 --静态代理/动态代理{JDK/cglib}
1.spring 不会自动去寻找注解,必须告诉 spring 哪些包下的类中可能有注解;使用注解来取代配置文件.1.1 引入xmlns:context ,指定扫描范围 <context:comp ...
- AOP学习心得&jdk动态代理与cglib比较
什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP引入 ...
- Spring AOP详解 、 JDK动态代理、CGLib动态代理
AOP是Aspect Oriented Programing的简称,面向切面编程.AOP适合于那些具有横切逻辑的应用:如性能监测,访问控制,事务管理以及日志记录.AOP将这些分散在各个业务逻辑中的代码 ...
- 【转载】Spring AOP详解 、 JDK动态代理、CGLib动态代理
Spring AOP详解 . JDK动态代理.CGLib动态代理 原文地址:https://www.cnblogs.com/kukudelaomao/p/5897893.html AOP是Aspec ...
- 017 Java中的静态代理、JDK动态代理、cglib动态代理
一.静态代理 代理模式是常用设计模式的一种,我们在软件设计时常用的代理一般是指静态代理,也就是在代码中显式指定的代理. 静态代理由业务实现类.业务代理类两部分组成.业务实现类负责实现主要的业务方法,业 ...
- JDK动态代理与CGLib动态代理相关问题
导读: 1.JDK动态代理原理是什么?为什么不支持类的代理? 2.JDK动态代理实例 3.CGLib代理原理是什么? 4.CGLib代理实例 5.JDK动态代理与CGLib代理的区别是什么? 6.总结 ...
- Java之代理(jdk静态代理,jdk动态代理,cglib动态代理,aop,aspectj)
一.概念 代理是什么呢?举个例子,一个公司是卖摄像头的,但公司不直接跟用户打交道,而是通过代理商跟用户打交道.如果:公司接口中有一个卖产品的方法,那么公司需要实现这个方法,而代理商也必须实现这个方法. ...
- 动态代理 JDK动态代理 CGLIB代理
代理模式:代理类和被代理类实现共同的接口(或继承),代理类中存有指向被代理类的索引,实际执行时通过调用代理类的方法.实际执行的是被代理类的方法. 而AOP,是通过动态代理实现的. 一.简单来说: JD ...
- 动态代理jdk和cglib的区别
学习来源贴:http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类, ...
- JDK动态代理、CGLib动态代理
JDK动态代理源码 一.public static Object newProxyInstance ——> 调用下面这个方法二.Class<?> cl = getProxyClass ...
随机推荐
- MySQL8.0 忘记密码、重置密码
修改my.cnf [mysqld] 域中添加skip-grant-tables 重启mysqld服务 systemctl restart mysqld 重新使用空密码登录,直接敲回车 mysql -u ...
- 关键路径——CriticalPath算法
背景:本文是在小甲鱼数据结构教学视频中的代码的基础上,添加详细注释而完成的.该段代码并不完整,仅摘录了核心算法部分,结合自己的思考,谈谈理解. 关键路径: 即决定一项工程的完成时间的路径. 如下图所示 ...
- ISTQB认证测试工程师基础大纲(2019.12.25)
1.本文档目的: 用于生成认证测试员基础级考试题. 本大纲中除了简介和附录外,考核通常包含了所有K1级别的内容,因此,应试者可能会被考到本大纲中要求识别,牢记,或记忆的关键词或概念.在本大纲中,每章开 ...
- Rocket - tilelink - RegionReplicator
https://mp.weixin.qq.com/s/XZVCdt50tM6lavchGm9GRg 简单介绍RegionReplicator的实现. 1. 基本介绍 根据mask ...
- jchdl - GSL实例 - LogicalLeft
https://mp.weixin.qq.com/s/WNm4bLWzZ0oWHWa7HQ6Y6w 逻辑左移,继承自Shifter类.只需要实现shift方法即可. 参考链接 https:// ...
- 高性能可扩展mysql 笔记(五)商品实体、订单实体、DB规划
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 一.商品模块 商品实体信息所存储的表包括: 品牌信息表: create table `brand_i ...
- Java实现 LeetCode 331 验证二叉树的前序序列化
331. 验证二叉树的前序序列化 序列化二叉树的一种方法是使用前序遍历.当我们遇到一个非空节点时,我们可以记录下这个节点的值.如果它是一个空节点,我们可以使用一个标记值记录,例如 #. _9_ / \ ...
- Java实现 LeetCode 56 合并区间
56. 合并区间 给出一个区间的集合,请合并所有重叠的区间. 示例 1: 输入: [[1,3],[2,6],[8,10],[15,18]] 输出: [[1,6],[8,10],[15,18]] 解释: ...
- Python学习之斐波那契数列实现篇
描述 一个斐波那契序列,F(0) = 0, F(1) = 1, F(n) = F(n-1) + F(n-2) (n>=2),根据n的值,计算斐波那契数F(n),其中0≤n≤1000. 输入 输入 ...
- Laravel中Homestead添加多站点时遇到问题
Homestead做Laravel的开发还是很方便的,但是在添加多站点的时候,发现几个坑,来做个记录. 首先,官方文档给了修改homestead.yaml文件的方式,只需要在sites字节下添加一个新 ...