jdk动态代理
什么是动态代理
在程序运行期间,创建目标对象的代理对象,并对目标对象中的方法进行功能性增强的一种技术。
为什么需要动态代理
1.功能增强。当前代码不能满足新需求但又不能改动以前代码时,就可以考虑使用代理,通过代理类,扩展原有类的功能。
2.降低耦合。程序设计时,要遵循一个叫做“单一职责”的原则,该原则要求每个类功能尽可能单一,为什么要单一,因为只有功能单一这个类被改动的可能性才会最小,减少类与类之间的依赖。
DK动态代理的实现
invoke():表示代理对象要执行的功能代码,你的代理类要完成的功能就写在invoke()方法中
(1)代理类要完成的功能
调用目标方法,执行目标方法的功能
增强功能
(2)invoke方法
invoke(Object proxy, Method method, Object[] args)
method:目标类中的方法,jdk负责提供method对象
Object[] args:目标类中的参数
Object proxy:jdk创建的代理对象,无需赋值
(3)使用过程
InvocationHandler接口:表示代理要干什么(定义目标类要完成的功能)
创建目标类实现接口
创建InvocationHandler接口的实现类,在invoke方法中完成代理类的功能
invoke方法:重写invoke方法,把原来静态代理中代理类要完成的功能写在方法内
method.invoke()是用来执行目标方法的
使用Proxy类的静态方法,来创建代理对象,并把返回值转换为接口类型
核心的对象,创建代理对象,之前的对象都是new类的构造方法,现在我们使用的是Proxy类的方法,代替new的使用
方法newProxyInstance(),作用是创建代理对象,需要三个参数
实现动态代理的步骤:
1.创建接口,定义目标类要完成的功能
public interface UsbSell {
float sell(float price);
}
2.实现目标类要完成功能的接口
public class UsbFactory implements UsbSell {
@Override
public float sell(float price) {
System.out.println("目标类");
return 70f;//厂家的U盘价格
}
}
3.实现InvocationHandler 接口,重写invoke方法。
1.在invoke中调用目标方法。
2.增强功能
//必须实现InvocationHandler接口,完成代理类的功能(调用目标方法、功能增强)
public class MySellHandler implements InvocationHandler {
private Object target=null;
//动态代理的目标对象是活动的,需要传入进来,传进来的是谁就给谁创建代理
public MySellHandler(Object target){
this.target=target;
}
//args代表传进来的参数(100)
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object res=null;
res=method.invoke(target,args);
if(res!=null){
Float price=(Float)res;
price=price+25;
res=price;
}
System.out.println("淘宝商家返回5元优惠券");
return res;
}
}
4.使用Proxy类的静态方法,创建代理对象。并把返回至转为接口类型。
public class Test {
public static void main(String[] args) {
//创建目标对象
UsbSell usbFactory=new UsbFactory();
//创建invocationHandler对象
InvocationHandler invocationHandler=new MySellHandler(usbFactory);
//创建代理对象
UsbSell proxy= (UsbSell) Proxy.newProxyInstance(
usbFactory.getClass().getClassLoader(),
usbFactory.getClass().getInterfaces(),
invocationHandler
);
System.out.println(proxy.sell(100));
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了