Java中的动态代理基本操作

动态代理

特点:字节码随用随创建,随用随加载
作用:不修改源码的基础上对方法进行加强

分类:

1.基于接口的动态代理(JDK)
要求:被代理的类至少实现一个接口,否则不能被代理
	创建代理对象:使用JDK中Proxy类的newProxyInstance方法
	参数:
		ClassLoader:类加载器
			用于加载被代理对象字节码,写法固定
		Class[]:字节码数组
			用于让代理对象和被代理对象有相同的方法,写法固定
		InvocationHandler:提供增强的代码
			一般用匿名内部类实现该接口
2.基于子类的动态代理(cglib)
	要求:被代理的类不能用final修饰
	创建代理对象:使用第三方cglib库中Enhancer类中create方法
	参数:
		Class:字节码
			被代理对象的字节码
		Callback:提供增强的代码
			一般用该接口的子接口MethodInterceptor实现匿名内部类

注意:在使用cglib架包进行动态代理时,还应导入asm架包,两个架包可能会不兼容
cglib-2.2.jar和asm-3.3.jar兼容

参考链接:https://juejin.im/post/5e8ad506e51d4547165507b2
视频讲解:https://www.bilibili.com/video/BV1Sb411s7vP?p=54

例子

一个男孩tom喜欢一个女孩,他可以直接对女孩说“I like you as much as I like Java”。但是男孩tom比较腼腆,所以他请女孩的闺蜜jane进行转告,此时,女孩的闺蜜jane就是男孩tom的“代理”。

男孩类

package com.test;

public class Boy {
	//被代理的方法
    public void say(String name,String word){
        System.out.println(name+" say: '"+word+"'");
    }

    public void work(){
        System.out.println("I can earn 300 yuan a day");
    }
}

女孩类

package com.test;

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 Girl {
    public static void main(String[] args) {
    	//男孩Tom
        Boy tom = new Boy();
        tom.say("Tom","I like you as much as I like Java");
		tom.work();
        //使用基于cglib的动态代理
        //女孩闺蜜Jane,相当于Tom的代理人,中间传话的
        Boy jane = (Boy) Enhancer.create(tom.getClass(), new MethodInterceptor() {
            @Override
            public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                Object obj = null;
                if("say".equals(method.getName())){
                	args[0] = "Jane";
	                args[1] = "Tom like you as much as he like Java";//重新组织语言
                    obj = method.invoke(tom,args);//被代理的是tom
                }
                return obj;
            }
        });
        jane.say("Tom","I like you as much as I like Java");
        jane.work();//并不输出任何内容,只增强say方法的功能
    }
}

输出结果

**不使用代理
Tom say: 'I like you as much as I like Java'
I can earn 300 yuan a day

**使用代理
Jane say: 'Tom like you as much as he like Java'
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值