栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

动态代理(JDK动态代理)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

动态代理(JDK动态代理)

动态代理

作用:在不修改源码的基础下,对已有方法进行增强
特征:字节码随用随创建,随用随加载
分类:1.基于接口的动态代理(JDK动态代理) 2.基于子类的动态代理(CGLib动态代理)
本篇内容主要阐述基于接口的动态代理
基于接口的动态代理 使用要求:被代理类最少要实现一个接口
基于接口的动态代理是JDK官方提供的

如何创建一个代理对象:
涉及的类:java.lang.reflect.Proxy
	Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。
涉及的方法:
	static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
	参数:
        ClassLoader loader:
        	类加载器。用于加载代理对象的字节码。写的是:和被代理对象使用相同的类加载器。
        		因此:
        			代理哪个对象,就用哪个对象的getClass().getClassLoader()
        			固定写法
        Class[] interfaces:传递被代理人所实现的所有接口的class文件对象
        	字节码数组。用于让代理对象和被代理对象具有相同的行为(有相同的方法)
        	写的是:
        		如果被代理对象是一个普通类:
        			则写的是:被代理对象.getClass().getInterfaces();
        		如果被代理对象是一个接口:
        			则写的是:new Class[]{被代理接口.class}
        		固定写法
        InvocationHandler h:
        	一个接口。用于提供增强的代码的。
        	增强的代码:谁用谁写。
    返回值:
        Object:代理对象
举例说明

培养明星的接口
//培养明星的接口
public interface Star {
    //唱歌
    public abstract void changGe();
    //跳舞
    public abstract void tiaoWu();
    //rap
    public abstract void rap();
    //打篮球();
    public abstract void daLanQiu();
    //直播带货():
    public abstract String zhiBoDaiHuo(int money);
}
蔡徐坤类
//定义明星蔡徐坤类
public class CaiXuKun implements Star{
    @Override
    public void changGe() {
        System.out.println("蔡徐坤在唱歌!");
    }

    @Override
    public void tiaoWu() {
        System.out.println("蔡徐坤在跳舞!");
    }

    @Override
    public void rap() {
        System.out.println("蔡徐坤在rap!");
    }

    @Override
    public void daLanQiu() {
        System.out.println("蔡徐坤在打篮球!");
    }

    @Override
    public String zhiBoDaiHuo(int money) {
        System.out.println("蔡徐坤在直播带货,挣了"+money+"钱!");
        return "挣大钱了!";
    }
}
鹿晗类
//定义明星鹿晗类
public class LuHan implements Star{
    @Override
    public void changGe() {
        System.out.println("鹿晗在唱歌!");
    }

    @Override
    public void tiaoWu() {
        System.out.println("鹿晗在跳舞!");
    }

    @Override
    public void rap() {
        System.out.println("鹿晗在rap!");
    }

    @Override
    public void daLanQiu() {
        System.out.println("鹿晗在打篮球!");
    }

    @Override
    public String zhiBoDaiHuo(int money) {
        System.out.println("鹿晗在直播带货,挣了"+money+"钱!");
        return "挣大钱了!";
    }
}
测试类(代理类)
public class Demo01Proxy {
    public static void main(String[] args) {
        //创建蔡徐坤对象
        CaiXuKun cxk = new CaiXuKun();
        //没有使用动态代理,随意的调用蔡徐坤的方法
        //cxk.changGe();
        //cxk.tiaoWu();
        //创建蔡徐坤的代理人对象
        Star cxkProxy = (Star)Proxy.newProxyInstance(cxk.getClass().getClassLoader(), cxk.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //获取到拦截到的方法名称
                String name = method.getName();
                if("tiaoWu".equals(name)){
                    //对跳舞的方法进行增强
                    System.out.println("蔡徐坤在央视的舞台跳舞!");
                    return null;
                }
                if("zhiBoDaiHuo".equals(name)){
                    //不让蔡旭进行直播带货
                    throw new RuntimeException("不允许蔡徐坤直播带货!");
                }
                //其他的方法(唱歌,rap,打篮球)直接放行
                Object v = method.invoke(cxk, args);
                return v;
            }
        });
        //cxkProxy.changGe();//蔡徐坤在唱歌!
        //cxkProxy.tiaoWu();//蔡徐坤在央视的舞台跳舞!
        //cxkProxy.zhiBoDaiHuo(1);//RuntimeException: 不允许蔡徐坤直播带货!

        //创建鹿晗对象
        LuHan lh = new LuHan();
        //获取鹿晗对象的class文件对象
        Class lhClazz = lh.getClass();
        //创建鹿晗的代理人对象
        Star lhProxy = (Star)Proxy.newProxyInstance(lhClazz.getClassLoader(), lhClazz.getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //获取拦截鹿晗对象的方法名称
                String name = method.getName();
                if("changGe".equals(name)){
                    //对唱歌的方法进行增强
                    System.out.println("安排鹿晗在鸟巢的舞台唱歌!");
                    return null;
                }
                if("tiaoWu".equals(name)){
                    throw new RuntimeException("不允许鹿晗给粉丝跳舞!");
                }
                //其他的方法,直接放行(rap,打篮球,直播带货)
                Object v = method.invoke(lh, args);
                return v;
            }
        });
        //lhProxy.changGe();//安排鹿晗在鸟巢的舞台唱歌!
        //lhProxy.tiaoWu();//RuntimeException: 不允许鹿晗给粉丝跳舞!
        String s = lhProxy.zhiBoDaiHuo(100);//鹿晗在直播带货,挣了100钱!
        System.out.println(s);//挣大钱了!
    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/287032.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号