Skip to content

Commit df08f9f

Browse files
committed
CGLib动态代理
1 parent d469e7e commit df08f9f

4 files changed

Lines changed: 116 additions & 0 deletions

File tree

pattern/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@
8989
- [x] [动态代理__DbRouteProxyTest](src/main/java/com/cpucode/pattern/proxy/db/route/proxy/dynamic/DbRouteProxyTest.java)
9090
- [x] [JDK动态代理__JDKProxyTest](src/main/java/com/cpucode/pattern/proxy/dynamicproxy/jdkproxy/JDKProxyTest.java)
9191
- [x] [JDK手写实现__GPProxyTest](src/main/java/com/cpucode/pattern/proxy/dynamicproxy/gpproxy/GPProxyTest.java)
92+
- [x] [CGLib动态代理__CglibTest](src/main/java/com/cpucode/pattern/proxy/dynamicproxy/cglibproxy/CglibTest.java)
93+
9294

9395

9496
## [适配器模式]()
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.cpucode.pattern.proxy.dynamicproxy.cglibproxy;
2+
3+
import net.sf.cglib.proxy.Enhancer;
4+
import net.sf.cglib.proxy.MethodInterceptor;
5+
import net.sf.cglib.proxy.MethodProxy;
6+
7+
import java.lang.reflect.Method;
8+
9+
/**
10+
* CGLib 代理的使用,还是以媒婆为例
11+
*
12+
* @author : cpucode
13+
* @date : 2021/5/30
14+
* @time : 16:44
15+
* @github : https://github.com/CPU-Code
16+
* @csdn : https://blog.csdn.net/qq_44226094
17+
*/
18+
public class CglibMeipo implements MethodInterceptor {
19+
public Object getInstance(Class<?> clazz) throws Exception{
20+
Enhancer enhancer = new Enhancer();
21+
22+
//要把哪个设置为即将生成的新类父类
23+
enhancer.setSuperclass(clazz);
24+
enhancer.setCallback(this);
25+
26+
return enhancer.create();
27+
}
28+
29+
@Override
30+
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
31+
//业务的增强
32+
before();
33+
34+
Object obj = methodProxy.invokeSuper(o, objects);
35+
36+
after();
37+
return obj;
38+
}
39+
40+
private void before(){
41+
System.out.println("我是媒婆: 我要给你找对象, 现在已经拿到你的需求");
42+
System.out.println("开始物色");
43+
}
44+
45+
private void after(){
46+
System.out.println("如果合适的话, 就准备办事");
47+
}
48+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package com.cpucode.pattern.proxy.dynamicproxy.cglibproxy;
2+
3+
import net.sf.cglib.core.DebuggingClassWriter;
4+
5+
/**
6+
* CGLib 代理的目标对象不需要实现任何接口,它是通过动态继承目标对象实现的动态代理
7+
*
8+
* CGLib 和 JDK 动态代理对比
9+
* 1.JDK 动态代理是实现了被代理对象的接口,CGLib 是继承了被代理对象。
10+
* 2.JDK 和 CGLib 都是在运行期生成字节码,JDK 是直接写 Class 字节码,
11+
* CGLib 使用 ASM框架写 Class 字节码,Cglib 代理实现更复杂,生成代理类比 JDK 效率低。
12+
* 3.JDK 调用代理方法,是通过反射机制调用,
13+
* CGLib 是通过 FastClass 机制直接调用方法,CGLib 执行效率更高
14+
*
15+
* JDK是采用读取接口的信息
16+
* CGLib覆盖父类方法
17+
* 目的:都是生成一个新的类,去实现增强代码逻辑的功能
18+
*
19+
* JDK Proxy 对于用户而言,必须要有一个接口实现,目标类相对来说复杂
20+
* CGLib 可以代理任意一个普通的类,没有任何要求
21+
*
22+
* CGLib 生成代理逻辑更复杂,效率,调用效率更高,生成一个包含了所有的逻辑的FastClass,不再需要反射调用
23+
* JDK Proxy生成代理的逻辑简单,执行效率相对要低,每次都要反射动态调用
24+
*
25+
* CGLib 有个坑,CGLib不能代理 final 的方法
26+
*
27+
* CGLib 动态代理执行代理方法效率 :
28+
* 为代理类和被代理类各生成一个 Class,这个 Class 会为代理类或被代理类的方法分配一个 index(int 类型)。
29+
* 这个 index 当做一个入参,FastClass就可以直接定位要调用的方法直接进行调用,这样省去了反射调用,
30+
* 所以调用效率比 JDK 动态代理通过反射调用高
31+
*
32+
* @author : cpucode
33+
* @date : 2021/5/30
34+
* @time : 16:50
35+
* @github : https://github.com/CPU-Code
36+
* @csdn : https://blog.csdn.net/qq_44226094
37+
*/
38+
public class CglibTest {
39+
public static void main(String[] args) {
40+
41+
try {
42+
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,
43+
"D://cglib_proxy_classes");
44+
45+
Customer obj = (Customer)new CglibMeipo().getInstance(Customer.class);
46+
47+
obj.findLove();
48+
} catch (Exception e) {
49+
e.printStackTrace();
50+
}
51+
}
52+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.cpucode.pattern.proxy.dynamicproxy.cglibproxy;
2+
3+
/**
4+
* @author : cpucode
5+
* @date : 2021/5/30
6+
* @time : 16:49
7+
* @github : https://github.com/CPU-Code
8+
* @csdn : https://blog.csdn.net/qq_44226094
9+
*/
10+
public class Customer {
11+
public void findLove(){
12+
System.out.println("儿子要求:肤白貌美大长腿");
13+
}
14+
}

0 commit comments

Comments
 (0)