使用CGLIB实现动态代理
参考:https://blog.csdn.net/yhl_jxy/article/details/80633194#comments
CGLIB动态代理
定义:CGLIB(code genaration libary), 代码自动生成类库。
在程序运行中自动生成扩展类和实现java接口,是一个强大的高性能的代码生成包
CGLIB动态代理的实现
1)、导入cglib所需的jar包
2)、实现MethodIntercetor类,实现代理类对象的具体逻辑
重写intercept()方法,在intercept方法中实现代理的逻辑
intercept(Object o, Method method, Object[] Objects, MehodProxy methodProxy )
o: 被代理类对象
method: 被代理类的方法
objects: 被代理类方法的参数
methodProxy: 调用被代理类对象的参数
3)、使用Enhance生成代理类对象
enhance.create() //生成代理类对象
使用CGLIB实现延迟加载
MehodInterceptor实现类:
/**
* 实现代理的逻辑
* 步骤:
* --: 1、实现MethodInterceptor拦截器
* o: 被代理对象
* method: 被代理对象的方法
* objects: 被代理对象的方法参数
* methodProxy: 触发父类方法的对象
*/
public class DBQueryCglibMethodInterceptor implements MethodInterceptor {
DBQuery dbQuery = null;
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
if(dbQuery == null){
dbQuery = new DBQuery();
}
return dbQuery.Request();
}
}
真实类:
/**
* 使用cglib来实现数据库的查询
*/
public class DBQuery {
public String Request(){
return "数据库查询完毕";
}
}
使用类:
public class Client {
public static void main(String[] args) {
/**
* 创建增强类对象
*/
Enhancer enhancer = new Enhancer();
/**
* 创建增强类的父类对象
*/
enhancer.setSuperclass(DBQuery.class);
/**
* 创建拦截切入类
*/
enhancer.setCallback(new DBQueryCglibMethodInterceptor());
/**
* 创建代理对象
*/
DBQuery dbQueryProxy = (DBQuery) enhancer.create();
String result = dbQueryProxy.Request();
System.out.println(result);
}
}
结果:
数据库查询完毕
使用CGLIB增强原有类的功能
MethodIntercptor实现类
/**
* cglib代理逻辑切入类
* ---: intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy)
* o: 被代理类对象
* method: 要拦截的被代理类的方法
* objects:被代理类的方法参数
* methodyProxy: 要触发父类的方法对象
*/
public class CglibMethodInteceptor implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("插入前置通知");
Object object = methodProxy.invokeSuper(o, objects);
System.out.println("插入后置通知");
return object;
}
}
真实类:
/**
* 使用cglib实现动态代理,不用创建接口
*/
public class HelloService {
HelloService(){
System.out.println("HelloServie构造器");
}
public final String sayOthers(String name){
System.out.println("HelloService: sayOthers" +name);
return null;
}
public void sayHello(){
System.out.println("HelloService: sayHello");
}
public void sayByeBye(){
System.out.println("HelloService: sayByeBye");
}
}
使用类:
public class Client {
public static void main(String[] args) {
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\code");
/**
* 创建增强类对象
*/
Enhancer enhancer = new Enhancer();
/**
* 创建需要增强的父类对象
*/
enhancer.setSuperclass(HelloService.class);
/**
* 设置切入类对象
*/
enhancer.setCallback(new CglibMethodInteceptor());
/**
* 生成代理对象
*/
HelloService service = (HelloService) enhancer.create();
service.sayHello();
service.sayByeBye();
}
}
结果:
HelloServie构造器
插入前置通知
HelloService: sayHello
插入后置通知
插入前置通知
HelloService: sayByeBye
插入后置通知
使用CGLIB实现动态代理的更多相关文章
- cglib实现动态代理简单使用
Boss: package proxy.cglib; public class Boss{ public void findPerson() { System.out.println("我要 ...
- JDK 和 CGLib 实现动态代理和区别
JDK 和 CGLib 实现动态代理和区别 在日常的开发中,Spring AOP 是一个非常常用的功能.谈到 AOP,自然离不开动态代理. 那么,基于 JDK 和 CGLib 如何实现动态代理,他们之 ...
- jdk与cglib的动态代理
JDK动态代理中包含一个类和一个接口: InvocationHandler接口: public interface InvocationHandler { public Object invoke(O ...
- 详解Java动态代理机制(二)----cglib实现动态代理
上篇文章的结尾我们介绍了普通的jdk实现动态代理的主要不足在于:它只能代理实现了接口的类,如果一个类没有继承于任何的接口,那么就不能代理该类,原因是我们动态生成的所有代理类都必须继承Proxy这个类, ...
- JDK和CGLIB生成动态代理类的区别
关于动态代理和静态代理 当一个对象(客户端)不能或者不想直接引用另一个对象(目标对象),这时可以应用代理模式在这两者之间构建一个桥梁--代理对象. 按照代理对象的创建时期不同,可以分为两种: 静态代 ...
- CGLIB实现动态代理
JDK动态代理和CGLIB字节码生成的区别? * JDK动态代理只能对实现了接口的类生成代理,而不能针对类 * CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法 因为是继承 ...
- 【4】JDK和CGLIB生成动态代理类的区别
当一个对象(客户端)不能或者不想直接引用另一个对象(目标对象),这时可以应用代理模式在这两者之间构建一个桥梁--代理对象. 按照代理对象的创建时期不同,可以分为两种: 静态代理:事先写好代理对象类,在 ...
- JDK和CGLIB生成动态代理类的区别(转)
关于动态代理和静态代理 当一个对象(客户端)不能或者不想直接引用另一个对象(目标对象),这时可以应用代理模式在这两者之间构建一个桥梁--代理对象. 按照代理对象的创建时期不同,可以分为两种: 静态代 ...
- JDK和Cglib实现动态代理实例及优缺点分析
Spring AOP使用的核心技术是动态代理,说到动态代理就不得不和设计模式中的代理模式联系起来,通过代理模式我们可以对目标类进行功能增强,在某个方法的执行前后增加一些操作,例如计算方法执行效率.打印 ...
随机推荐
- linux-查看服务器内存使用情况(free top)
free命令:显示系统使用和空闲的内存情况,包括物理内存.交互区内存(swap)和内核缓冲区内存. [root@ipha-dev71- workspace]# free # kb total used ...
- 该虚拟机似乎正在使用中。 如果该虚拟机未在使用,请按“获取所有权(T)”按钮获取它的所有权。否则,请按“取消(C)”按钮以防损坏。 配置文件: ***.vmx。
打开虚拟机的时候,出现这样的问题: 该虚拟机似乎正在使用中. 如果该虚拟机未在使用,请按“获取所有权(T)”按钮获取它的所有权.否则,请按“取消(C)”按钮以防损坏. 配置文件: D:\VM\wi ...
- AI Conference 2018人工智能大会 参会总结
主 题:AI Conference 2018人工智能大会 时 间:2018.04.11-4.13 地 点:北京国际饭店会议中心 发起人:O'Reilly 和 Intel 参与部门:研发设计部 参会人员 ...
- 6、pytest -- 临时目录和文件
目录 1. 相关的fixture 1.1. tmp_path 1.2. tmp_path_factory 1.3. tmpdir 1.4. tmpdir_factory 1.5. 区别 2. 默认的基 ...
- 【暂时停更】Gungame更新下载平台
v1.0: 这是本游戏的第一个版本, 制作于2019.4.12. 控制 : Player1: wsad为移动, r键开炮(有朝向限制) Player2: ikjl为移动, p键开炮(有朝向限制) 下载 ...
- [考试反思]1008csp-s模拟测试64:契机
暴力没打满...有点垃圾... 考得稍绝望,啥也不会啊??? T3的测试点分治还写挂了... 其实就是没有沉下心好好的思考,在三道题上来回切换结果一个成型思路都没有 T2既然已经想到那一步了居然没有继 ...
- Java多线程中join、yield、sleep方法详解
在Java多线程编程中,Thread类是其中一个核心和关键的角色.因此,对该类中一些基础常用方法的理解和熟练使用是开发多线程代码的基础.本篇主要总结一下Thread中常用的一些静态方法的含义及代码中的 ...
- iOS开发高级分享 - iOS的可折叠表视图
导言 我曾经开发过一个iphone应用程序,它显示了大量的输入,这些输入分为不同的类别,在`UITableView`...若要更改其中一个输入的值,用户按下表视图中的对应行,并在出现的单独屏幕中更改该 ...
- js调用局部打印功能并还原
function printme() { //printMain为要打印的dom元素 window.document.body.innerHTML = document.getElementById( ...
- P4568 [JLOI2011]飞行路线(分层图)
机房dalao推荐写的...(标签分层图) 经过前几题的分层图的洗礼,我深刻地体会到了分层图的优点和好处(主要是不想打dp....) 先说题吧.... 很明确,模型是最短路,但是,怎么跑k个,是个问题 ...