【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 ...
随机推荐
- SpringBoot系列—简单的邮件系统
1. 效果发送效果图 2. 邮件开发准备工作 3. springboot引入mail服务 4. 启动应用,开始4种邮件发送测试 1. 效果发送效果图 连续发送了四封邮件:普通文本邮件,带附件的邮件,内 ...
- sqlmap tamper脚本备忘录与tamper脚本编写
查看sqlmap全部脚本 $ python sqlmap.py --list-tampers 使用方法 --tamper=TAMPER 2019.9更新后翻译 * apostrophemask.py- ...
- Asp.Net Mvc基于Fleck开发的多人网页版即时聊天室
一.项目的核心说明 1.Fleck这个是实现websocket一个比较简单第三方组件,它不需要安装额外的容器.本身也就几个接口可供调用. 2.项目是基于.net framework 4.7.2 ,在v ...
- 带你学够浪:Go语言基础系列-环境配置和 Hello world
文章每周持续更新,原创不易,「三连」让更多人看到是对我最大的肯定.可以微信搜索公众号「 后端技术学堂 」第一时间阅读(一般比博客早更新一到两篇) 前面几周陆陆续续写了一些后端技术的文章,包括数据库.微 ...
- ROS入门笔记(二):ROS安装与环境配置及卸载(重点)
ROS入门笔记(二):ROS安装与环境配置及卸载(重点) [TOC] 1 ROS安装步骤 1.1 ROS版本 ROS目前只支持在Linux系统上安装部署, 它的首选开发平台是Ubuntu. 发布时间 ...
- Redis 入门到分布式 (八)Redis Sentinel
个人博客网:https://wushaopei.github.io/ (你想要这里多有) sentinel-目录 主从复制高可用 安装配置 实现原理 架构说明 客户端连接 常见开发运维问题 一. ...
- Java实现 蓝桥杯 基础练习 01字串
基础练习 01字串 时间限制:1.0s 内存限制:256.0MB 提交此题 锦囊1 锦囊2 问题描述 对于长度为5位的一个01串,每一位都可能是0或1,一共有32种可能.它们的前几个是: 00000 ...
- Java实现LeetCode 139 单词拆分
public boolean wordBreak(String s, List<String> wordDict) { if(s.length() == 0){ return false; ...
- java实现取字母组成串
** 取字母组成串** A B C D中取5次,每个字母都可以重复取出,形成一个串. 现在要求,串中A出现的次数必须为偶数(0次也算偶数). 求可以形成多少种可能的串. 参考答案: 528 publi ...
- TZOJ 复习时间
描述 为了能过个好年,xhd开始复习了,于是每天晚上背着书往教室跑.为了追求更高的效率,xhd要根据难度值来选择合适的课程进行复习,复习后一门课的效率为前一门课之间的难度差的平方,而复习第一门课的效率 ...