当前位置:网站首页>Cglib代理-代码增强测试
Cglib代理-代码增强测试
2022-07-02 06:09:00 【一眉程序猿】
导包
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
编写方法拦截器
- 方法增强具体逻辑
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
import java.util.Arrays;
/** * 自定义 cglib 代理 * * @author Ara * @since 2022/6/20 */
public class MyCglibProxyMethodInterceptor<T> implements MethodInterceptor {
/** * 目标对象 */
private final T target;
/** * 构造方法 */
public MyCglibProxyMethodInterceptor(T target) {
this.target = target;
}
/** * 获取代理对象 */
public T getProxyObject(){
Enhancer enhancer = new Enhancer();
//设置父类 因为cglib是针对指定的类生成一个子类用于其增强行为
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(this);
return (T) enhancer.create();
}
// TODO 执行增强部分
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("执行前 方法参数: " + Arrays.toString(objects));
Object result = method.invoke(target, objects);
System.out.println("执行后 返回值: " + result);
return result;
}
}
编写待增强测试类
- 增强目标点
/** * 文章 Service * * @author Ara * @since 2022/6/20 */
public class ArticleService {
public String saveArticle(String article) {
System.out.printf("保存文章[%s]...%n", article);
return article;
}
}
编写测试
- 检验是否能够进行增强
public class MainTest {
public static void main(String[] args) {
ArticleService articleService = new ArticleService();
//声明Cglib方法拦截增强实现类
MyCglibProxyMethodInterceptor<ArticleService> cglibProxyMethodInterceptor = new MyCglibProxyMethodInterceptor<>(articleService);
// 获取代理类
ArticleService articleServiceProxy = cglibProxyMethodInterceptor.getProxyObject();
//使用代理类调用方法
articleServiceProxy.saveArticle("Java");
}
}
验证结果
小总结
简单对比cglib与JDK动态代理:
- 这里使用cglib进行代理时,不论其目标类是否实现了接口,都可以对其进行增强。
- 但是单独使用JDK动态代理,就只能增强实现了接口的类重写的方法。
以下是对cglib和JDK动态代理是否能够增强有无接口实现的类的对比代码,感兴趣的读者可以进行测试:
public class MainTest {
public static void main(String[] args) {
cglibProxyNoInterfaceTest();
}
/** * cglib代理(代理目标类未实现接口) */
private static void cglibProxyNoInterfaceTest(){
ArticleService articleService = new ArticleService();
//声明Cglib方法拦截增强实现类
MyCglibProxyMethodInterceptor<ArticleService> cglibProxyMethodInterceptor = new MyCglibProxyMethodInterceptor<>(articleService);
// 获取代理类
ArticleService articleServiceProxy = cglibProxyMethodInterceptor.getProxyObject();
//使用代理类调用方法
articleServiceProxy.saveArticle("Java");
}
/** * cglib代理(代理目标类实现了接口) */
private static void cglibProxyHasInterfaceTest(){
UserService userService = new UserServiceImpl();
//声明Cglib方法拦截增强实现类
MyCglibProxyMethodInterceptor<UserService> cglibProxyMethodInterceptor = new MyCglibProxyMethodInterceptor<>(userService);
// 获取代理类
UserService userServiceProxy = cglibProxyMethodInterceptor.getProxyObject();
//使用代理类调用方法
userServiceProxy.add("Ara");
}
/** * JDK动态代理(代理目标类实现了接口) */
private static void jdkDynamicProxyHasInterfaceTest(){
//原对象 (接口接收参数)
UserService userService = new UserServiceImpl();
//声明增强处理程序
MyJdkProxyInvocationHandler<UserService> proxyInvocationHandler = new MyJdkProxyInvocationHandler<>(userService);
//获取代理对象
UserService proxyUserService = proxyInvocationHandler.getProxyObject();
//使用代理对象来调用方法
proxyUserService.add("Ara");
}
/** * JDK动态代理(代理目标类未实现接口) * 有误,使用JDK动态代理实现增强,必须要求代理目标实现了接口 */
private static void jdkDynamicProxyNoInterfaceTest(){
ArticleService articleService = new ArticleService();
//声明增强处理程序
MyJdkProxyInvocationHandler<ArticleService> proxyInvocationHandler = new MyJdkProxyInvocationHandler<>(articleService);
//获取代理对象
ArticleService proxyArticleService = proxyInvocationHandler.getProxyObject();
//使用代理对象来调用方法
proxyArticleService.saveArticle("Java");
}
}
边栏推荐
- Keepalived installation, use and quick start
- Problems encountered in uni app development (continuous update)
- Common means of modeling: combination
- Stc8h8k Series Assembly and c51 Real combat - NIXIE TUBE displays ADC, Key Series port reply Key number and ADC value
- 网络相关知识(硬件工程师)
- 经典文献阅读之--Deformable DETR
- Classic literature reading -- deformable Detr
- Format check JS
- 深入学习JVM底层(五):类加载机制
- Happy Lantern Festival | Qiming cloud invites you to guess lantern riddles
猜你喜欢
Detailed steps of JS foreground parsing of complex JSON data "case: I"
LeetCode 90. Subset II
Current situation analysis of Devops and noops
Let every developer use machine learning technology
Unity shader learning notes (3) URP rendering pipeline shaded PBR shader template (ASE optimized version)
500. Keyboard line
Replace Django database with MySQL (attributeerror: 'STR' object has no attribute 'decode')
ES6的详细注解
网络相关知识(硬件工程师)
穀歌出海創業加速器報名倒計時 3 天,創業人闖關指南提前收藏!
随机推荐
No subject alternative DNS name matching updates. jenkins. IO found, the reason for the error and how to solve it
经典文献阅读之--Deformable DETR
Bgp Routing preference Rules and notice Principles
Contest3147 - game 38 of 2021 Freshmen's personal training match_ F: Polyhedral dice
VRRP之监视上行链路
Database learning summary 5
Mock simulate the background return data with mockjs
Classic literature reading -- deformable Detr
社区说|Kotlin Flow 的原理与设计哲学
LeetCode 283. 移动零
Pbootcms collection and warehousing tutorial quick collection release
加密压缩文件解密技巧
LeetCode 77. combination
STC8H8K系列匯編和C51實戰——數碼管顯示ADC、按鍵串口回複按鍵號與ADC數值
MUI底部导航的样式修改
Web page user step-by-step operation guide plug-in driver js
格式校验js
Servlet web XML configuration details (3.0)
Detailed notes of ES6
Redis key value database [primary]