使用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使用的核心技术是动态代理,说到动态代理就不得不和设计模式中的代理模式联系起来,通过代理模式我们可以对目标类进行功能增强,在某个方法的执行前后增加一些操作,例如计算方法执行效率.打印 ...
随机推荐
- SpringBoot是如何动起来的?
程序入口 SpringApplication.run(BeautyApplication.class, args); 执行此方法来加载整个SpringBoot的环境. 1. 从哪儿开始? Spring ...
- if-elif-else分支判断语句(附加continue和break)---举例说明
一.分支循环语句: a=input("请输入一个五位数字") if(len(a)!=5): print("输入的数字不合格"); elif(a[0::]==a[ ...
- Qt 表格的使用
参考 http://doc.qt.io/qt-5/qtablewidget.html http://doc.qt.io/qt-5/qtablewidgetitem.html https://blog. ...
- 《HTML5+CSS3+JavaScript 从入门到精通(标准版)》学习笔记(一)
以下是以代码形式书写的笔记,本系列会持续更新,主要内容预计是类似下文的笔记,兼或一些思考与小项目,希望对你会有所帮助 1 <!-- --> <!DOCTYPE html>< ...
- postgresql被注入之后
本来只是贪便宜买了个一年特价的阿里云服务器,做做测试什么的,结果不知道哪一天开始阿里云安全中心就开始给我发什么安全提示类的信息,一开始我并不在意,因为这些都是套路,不过是想让我升级购买高防盾罢了,反正 ...
- SpringBoot异常处理统一封装我来做-使用篇
SpringBoot异常处理统一封装我来做-使用篇 简介 重复功能我来写.在 SpringBoot 项目里都有全局异常处理以及返回包装等,返回前端是带上succ.code.msg.data等字段.单个 ...
- JVM概述和类加载器
JVM概述 1.Java虚拟机所管理的内存包括以下几个运行时数据区域: ①.程序计数器 程序计数器是一块较小的内存空间,可以看做是当前线程所执行的字节码的行号指示器,字节码解释器工作时就是 ...
- 11 一步一步Zabbix4.4.0系统教你实现sendEmail邮件报警
点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 一步一步Zabbix4.4.0系统教你实现sendEmail邮件报警 sendEmail是一个轻量 ...
- 在虚拟机上的关于Apache(阿帕奇)(2)开启个人用户主页功能
首先下载httpd服务 在这里我们主要谈一谈个人主页功能分为不加密和加密两种 不加密 我们先来建立几个用户,使用命令:useradd longshisan 使用命令: Passwd longs ...
- [py2neo]Ubuntu14 安装py2neo失败问题解决
环境 1.操作系统Ubuntu14 2.py2neo版本4.1 3.python版本python3.4 问题 pip install py2neo==4.1 安装失败,提示: Cannot unin ...