动态代理(一)
时间:2022-06-13
本文章向大家介绍动态代理(一),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
代理模式是Java的一种设计模式,开发中可能会有一种场景,某个类的方法需要补充,但是由于不想在原有的类基础上改动,该如何做呢,如下:
接口:
public interface ProxyUserService{
String getUserMobile(String name);
}
public class ProxyUserServiceImpl implements ProxyUserService{
@Override
public String getUserMobile(String name) {
return name;
}
}
public class ProxyUserServiceStaticImpl implements ProxyUserService{
private ProxyUserService proxyUserService;
public ProxyUserServiceStaticImpl(ProxyUserService proxyUserService) {
this.proxyUserService = proxyUserService;
}
@Override
public String getUserMobile(String name) {
//before
String result = roxyUserService.getUserMobile(name);
//after
return result;
}
}
上面可以看出,ProxyUserServiceStaticImpl实现了ProxyUserService接口,构造方法中用ProxyUserService子类初始化,在创建ProxyUserServiceStaticImpl对象时,构造方法中传入ProxyUserServiceImpl实例即可,它的getUserMobile方法其实是对ProxyUserServiceImpl类的一种功能增强.Java中有木有其他方法来帮助我们实现这一功能呢?下面就来谈谈jdk动态代理、cglib动态代理.
jdk动态代理
public class ProxyUserServiceProxy implements InvocationHandler{
/**
* 被代理对象
*/
private Object target;
private static final Logger logger = LoggerFactory.getLogger(ProxyUserServiceProxy.class);
public ProxyUserServiceProxy(Object target) {
this.target = target;
}
/**
*
* @param proxy 代理对象
* @param method 被调用的方法
* @param args 方法的参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//执行前预处理
Object result = method.invoke(target,args);//调用被代理类中的方法
//执行后处理
return result;
}
public static void main(String[] args) {
ProxyUserServiceImpl proxyUserServiceImpl= new ProxyUserServiceImpl();
ProxyUserServiceProxy proxyUserServiceProxy = new ProxyUserServiceProxy(proxyUserServiceImpl);
ProxyUserService proxyUserService = (ProxyUserService)Proxy.newProxyInstance(proxyUserServiceImpl.getClass().getClassLoader(),proxyUserServiceImpl.getClass().getInterfaces(),proxyUserServiceProxy);
logger.info(proxyUserService.getUserMobile("18883845677"));
}
}
ProxyUserServiceProxy代理类实现了InvocationHandler接口,重写invoke方法,在调用被代理类方法前后可以实现需要的逻辑.
cglib动态代理
public class ProxyUserServiceCgLib implements MethodInterceptor{
private static final Logger logger = LoggerFactory.getLogger(ProxyUserServiceCgLib.class);
//回调方法
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//执行前预处理
Object returnObj = methodProxy.invokeSuper(o,objects);
//执行完处理
return returnObj;
}
public static void main(String[] args) {
ProxyUserServiceCgLib proxyUserServiceCgLib = new ProxyUserServiceCgLib();
Enhancer enhancer = new Enhancer();
//对目标对象创建子类对象
enhancer.setSuperclass(ProxyUserServiceImpl.class);
//设置回调
enhancer.setCallback(proxyUserServiceCgLib);
ProxyUserService proxyUserService = (ProxyUserService) enhancer.create();
logger.info(proxyUserService.getUserMobile("18888488585"));
}
}
ProxyUserServiceCgLib实现了MethodInterceptor接口,重写intercept方法,在其中实现具体逻辑.
总结
- jdk代理的目标对象必须实现接口
- cglib代理的目标对象可以不实现接口
- 如果目标对象没有实现接口,使用cglib
- 洛谷P3201 [HNOI2009]梦幻布丁
- 洛谷P3374 【模板】树状数组 1(CDQ分治)
- 自然语言处理基础知识1. 分词(Word Cut)2. 词性标注(POS Tag)3.自动标注4.文本分类5.评估6.从文本提取信息7.分析句子结构《python自然语言处理》各章总结:
- 洛谷P3384 【模板】树链剖分
- 洛谷P2147 [SDOI2008]Cave 洞穴勘测
- linux基础
- 洛谷P3178 [HAOI2015]树上操作
- Numpy 修炼之道 (6)—— 复制和视图
- 事务日志已满,原因为“ACTIVE_TRANSACTION”
- 【 关关的刷题日记46】Leetcode 28. Implement strStr()
- Python的机器学习库之Sklearn快速入门1.基本概述2.入门实践3.部分结果
- 再论 ASP.NET 中获取客户端IP地址
- 洛谷P3038 [USACO11DEC]牧草种植Grass Planting
- 【 关关的刷题日记47】Leetcode 38. Count and Say
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法