Java JDK与cglib * 有什么区别
作者:王佑辉 时间:2023-07-23 08:10:15
一、说明
1.spring aop中的 * 主要有两种方式,jdk * 和cglib *
2.从实现接口、继承父类的角度讨论区别
3.从限制角度讨论区别
4.从性能上讨论区别
二、区别
1.jdk * 只提供实现接口的目标类代理,不支持没有实现接口的目标类的代理。如果目标类没有实现接口,只能用cglib代理
2.jdk * 会在运行时为目标类生成一个 * 类$proxy*.class。cglib的底层是通过ASM在运行时动态生成目标类的子类,还会有其它类
3. jdk * 的代理类实现了目标类实现的接口,并且会实现接口所有方法来代码增强。cglib * 会重写父类所有的方法来代码增强
4.jdk * 调用时先去调用处理类进行增强,再通过反射的方式调用目标类的方法。cglib * 调用时先通过代理类进行增强,再直接调用父类对应的方法进行调用目标方法
5.jdk * 如果目标类未实现接口则无法代理,cglib是通过继承的方式来 * ,若目标类被final关键字修饰,则无法使用cglib做 *
6.性能上:在老版的jdk,jdk代理生成的类速度快,通过反射调用慢,cglib是jdk代理速度的10倍左右,jdk在版本每次升级都会有很大的性能提升,cglib停滞不前,jdk7 8的 * 性能在1万次实验中比cglib要快20%左右
三、代码示例
3.1 静态代理
package com.proxy.staticproxy;
public interface SellTicket {
void sell();
}
package com.proxy.staticproxy;
public class TrainStation implements SellTicket{
@Override
public void sell() {
System.out.println("火车站售票");
}
}
package com.proxy.staticproxy;
public class ProxyPoint implements SellTicket{
//声明火车类对象
private TrainStation trainStation = new TrainStation();
@Override
public void sell() {
System.out.println("代售点收取服务费");
trainStation.sell();
}
public static void main(String[] args) {
ProxyPoint proxyPoint = new ProxyPoint();
proxyPoint.sell();
}
}
3.2 jdk *
package com.proxy.jdkproxy;
import com.proxy.staticproxy.SellTicket;
import com.proxy.staticproxy.TrainStation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyFactory {
private TrainStation trainStation = new TrainStation();
public SellTicket getProxyPoint() {
/**
* ClassLoader loader: 类加载器,用于加载代理类。可以通过目标对象获取类加载器
* Class<?>[] interfaces: 代理类实现的接口的字节码对象
* InvocationHandler h: 代理对象的调用处理程序
*/
SellTicket sellTicket = (SellTicket)Proxy.newProxyInstance(trainStation.getClass().getClassLoader(), trainStation.getClass().getInterfaces(),
new InvocationHandler() {
/**
* @param proxy 代理对象 proxyObject是同一个对象,在invoke方法中基本不用
* @param method 对接口中的方法进行封装的method对象
* @param args 调用方法的实际参数
* @return 方法返回值
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 代码增强
System.out.println("代理点收取服务费");
Object object = method.invoke(trainStation, args);
return object;
}
});
return sellTicket;
}
public static void main(String[] args) {
ProxyFactory proxyPoint = new ProxyFactory();
SellTicket sellTicket = proxyPoint.getProxyPoint();
sellTicket.sell();
}
}
3.3 cglib *
<!-- 引入cglib依赖包-->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
package com.cglib;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class ProxyFactory implements MethodInterceptor {
private TrainStation trainStation = new TrainStation();
public TrainStation getTrainStation(){
//创建Enhancer对象,类似于JDK代理中的Proxy类
Enhancer enhancer = new Enhancer();
//设置父类的字节码对象
enhancer.setSuperclass(TrainStation.class);
//设置回调函数
enhancer.setCallback(this);
//创建代理对象
TrainStation trainStation = (TrainStation)enhancer.create();
return trainStation;
}
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
// 代码增强
System.out.println("代售点收取服务费用");
Object obj = method.invoke(trainStation, objects);
return obj;
}
public static void main(String[] args) throws Exception {
ProxyFactory proxyFactory = new ProxyFactory();
TrainStation trainStation = proxyFactory.getTrainStation();
trainStation.sell();
}
}
来源:https://blog.csdn.net/qq_32088869/article/details/129655075
标签:Java,JDK,cglib, ,
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
c# 将Minio.exe注册成windows服务
2022-09-25 20:51:18
![](https://img.aspxhome.com/file/2023/8/96358_0s.png)
解析SpringBoot整合SpringDataRedis的过程
2022-07-05 06:45:37
![](https://img.aspxhome.com/file/2023/8/83418_0s.png)
Java生成PDF文件的实例代码
2022-05-24 07:22:37
java排序算法之冒泡排序
2023-04-05 21:03:42
![](https://img.aspxhome.com/file/2023/7/72637_0s.gif)
java实现将域名解析成ip示例
2021-11-20 10:33:33
java中this的n种使用方法
2023-12-23 13:13:23
![](https://img.aspxhome.com/file/2023/3/62063_0s.png)
每日六道java新手入门面试题,通往自由的道路--多线程
2022-12-13 16:04:07
![](https://img.aspxhome.com/file/2023/6/70266_0s.jpg)
Android实现ViewPager无限循环效果(一)
2022-08-02 18:58:34
java面向对象:API(接口)与集合(ArrayList)
2021-06-07 03:28:19
![](https://img.aspxhome.com/file/2023/0/125590_0s.png)
Java多线程实现Runnable方式
2022-06-29 17:09:46
使用AOP的@Around后无返回值的解决
2023-11-24 13:04:09
Android实现自动点击无障碍服务功能的实例代码
2022-08-31 12:14:26
![](https://img.aspxhome.com/file/2023/3/137803_0s.gif)
基于OpenCv与JVM实现加载保存图像功能(JAVA 图像处理)
2021-12-27 23:09:33
![](https://img.aspxhome.com/file/2023/2/104062_0s.jpg)
Scala数据库连接池的简单实现
2023-07-14 14:19:37
![](https://img.aspxhome.com/file/2023/8/57698_0s.jpg)
Android实现带指示点的自动轮播无限循环效果
2021-12-09 19:22:44
C# 实现PPT 每一页转成图片过程解析
2023-02-21 10:01:27
![](https://img.aspxhome.com/file/2023/5/119505_0s.jpg)
简单谈谈android studio 的单元测试
2021-08-21 14:52:30
![](https://img.aspxhome.com/file/2023/1/129021_0s.png)
Java中notify和notifyAll的区别及何时使用
2022-07-03 02:08:43
Spring Boot Debug调试过程图解
2023-12-13 10:27:33
![](https://img.aspxhome.com/file/2023/7/62497_0s.png)
Spring AOP如何整合redis(注解方式)实现缓存统一管理详解
2023-11-19 06:09:27