JKD动态代理

在介绍动态代理前先咱们先简单了解一下静态代理的概念

1.静态代理

 巨星类

public class BigStar implements Star{

    private String name ;

    public BigStar(String name) {
        this.name = name;
    }

    @Override
    public void sing() {
        System.out.println(name + "在唱歌");
    }

    @Override
    public void dance() {
        System.out.println(name + "在跳舞");
    }
}

由巨星类抽象出的 巨星接口

public interface Star {

    public void sing();

    public void dance();
}

代理类 

public class proxy implements Star{

    private Star star;

    public void setStar(Star star) {
        this.star = star;
    }

    @Override
    public void sing() {
        System.out.println("收费");
        star.sing();
        System.out.println("打扫场地");
    }

    @Override
    public void dance() {
        System.out.println("收费");
        star.dance();
        System.out.println("打扫场地");
    }
}

 静态代理执行

public static void main(String[] args) {
    
    //创建明星
    BigStar star = new BigStar("ycy");
    //创建代理类
    proxy proxy_temp = new proxy();
    //代理人代理明星
    proxy_temp.setStar(star);
    //代理类执行sing 方法 调用明星的sing方法
    proxy_temp.sing();

静态代理总结:本质上就是在原来的明星类上加了一层 这样就可以在不修改原来底层dao代码的基础上完成我们想要添加的任务。这样可以降低代码的耦合性 有利于我们维护代码的有效性。

2.动态代理

巨星类

public class BigStar implements Star{

    private String name ;

    public BigStar(String name) {
        this.name = name;
    }

    @Override
    public void sing() {
        System.out.println(name + "在唱歌");
    }

    @Override
    public void dance() {
        System.out.println(name + "在跳舞");
    }
}

 由巨星类抽象出的 巨星接口

public interface Star {

    public void sing();

    public void dance();
}

 代理类工具

public class ProxyUtils {

    public static Star createProxy(BigStar bigStar){

        //创建代理类
//        ProxyUtils.class.getClassLoader(),  类加载器
//        new Class[]{Star.class},            代理类长什么样
//        new InvocationHandler()            这是一个接口 我们用匿名内部类 实现这个接口里的invoke方法
        Star proxy = (Star)Proxy.newProxyInstance(ProxyUtils.class.getClassLoader(), new Class[]{Star.class}, new InvocationHandler() {
            @Override
            //当代理类执行方法时 会执行invoke方法
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                if(method.getName().equals("sing")){
                    System.out.println("准备演唱会----");
                }else if(method.getName().equals("dance")){
                    System.out.println("准备舞蹈场地----");
                }else {
                }
                return method.invoke(bigStar,args);
            }
        });

        return proxy;
    }
}

 动态代理测试

        BigStar ycy= new BigStar("杨超越");

        System.out.println("----------------------------------");

        Star proxy = ProxyUtils.createProxy(ycy);

        proxy.dance();
        proxy.sing("好日子");

动态代理小结:

调用Proxy.newProxyInstance(ProxyUtils.class.getClassLoader(), new Class[]{Star.class}, new InvocationHandler())创建proxy代理对象 这其中我ProxyUtils.class.getClassLoader()为当前类的类加载器、 new Class[]{Star.class}表示我们要代理的接口长什么样 、new InvocationHandler()为我们需要重写里面的invoke方法

这个invoke方法就是在jdk动态代理类里加一层的关键,

public Object invoke(Object proxy, Method method, Object[] args)

这里的Object proxy代表我们要传入的被代理的对象, Method method表示方法对象(反射),Object[] args代表我们在调用代理类里的方法时传入的参数数组

代理类调用被代理类的过程(这里套用上面静态代理的说法):

1.创建明星(要被代理的对象)

2.使用工具创建代理人(经理人)

3.经理人调用自己的sing方法 

proxy.sing("好日子");

-》 这个sing方法会调用invoke方法(实际上调用任意经理人的方法都会先调用invoke方法): 

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    if(method.getName().equals("sing")){
        System.out.println("准备演唱会----");
    }else if(method.getName().equals("dance")){
        System.out.println("准备舞蹈场地----");
    }else {
    }
    return method.invoke(bigStar,args);
}  

--》在invoke方法里判断是哪个方法被调用了(利用反射method对象获取方法名)if(method.getName().equals("sing")){
    System.out.println("准备演唱会----");
}else if(method.getName().equals("dance")){
    System.out.println("准备舞蹈场地----");
}else {
}
-》调用明星中对应的方法(利用反射method对象调用明星的方法)
method.invoke(bigStar,args);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值