day22Java-Reflect-动态代理

动态代理

1.什么是代理(中介)

	目标对象/被代理对象 ------ 房主:真正的租房的方法
	代理对象 ------- 黑中介:有租房子的方法(调用房主的租房的方法)
	执行代理对象方法的对象 ---- 租房的人
	流程:我们要租房----->中介(租房的方法)------>房主(租房的方法)
	抽象:调用对象----->代理对象------>目标对象 

2.静态代理

静态代理图解:
图中的代理对象是自己编写一个类,去调用目标对象的方法,这就是静态代理。
在这里插入图片描述

3.动态代理

java.lang.reflect.Proxy

动态代理:不用手动编写一个代理对象,不需要编写与目标对象相同的方法,这个过程,在运行时的内存中动态生成代理对象。------字节码对象级别的代理对象

注意:JDK的Proxy方式实现的动态代理 目标对象必须有接口 没有接口不能实现jdk版动态代理

为什么要实现接口?
	代理对象和目标对象的方法肯定要一样,代理对象调用目标对象同名的方法结果可能是不一样的。代理对象是在目标对象方法基础上做操作。换言之目标对象有的方法,代理对象也要有。 	
	
举例:房东卖房子->中介(中介调用房东卖房子的方法)->其实中介也有一个卖房方法,但是中介可以在卖房前后搞一些外快。

动态代理的API:
在jdk的API中存在一个Proxy中存在一个生成动态代理的的方法newProxyInstance
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)

代码演示:

public class ProxyTest {
    public static void main(String[] args) {

        //动态创建代理对象,返回代理对象。
        //为什么可以TargerInterfacee接口接收?
        //代理对象和目标对象实现了同一接口,返回的又是代理对象,当然可以用TargerInterfacee接口接收。

        //Target.class.getClassLoader():代理对象需要和目标对象相同的类加载器。
        //Target.class.getInterfaces():获取目标对象接口,就相当于代理对象实现了目标对象接口(底层会操作)。
        //InvocationHandler:处理器中的invoke方法就是代理对象,每次调用都是执行的方法。
        TargerInterface ti = (TargerInterface) Proxy.newProxyInstance(Target.class.getClassLoader(),
                Target.class.getInterfaces(), new InvocationHandler() {
                  @Override
                   //被执行几次?------- 看代理对象调用方法几次
                   //代理对象调用接口相应方法 都是调用invoke
                 /*
                   * proxy:是代理对象(大部分不用上,如果直接打印就是死循环)
                   * method:代表的是目标方法的字节码对象
                   * args:代表是调用目标方法时参数(注意args:是从代理对象调用方法时传入的参数,然后再传给目标方法。)
                   */
                   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                       System.out.println("调用目标方法前执行操作");

                       //使用反射执行方法
                       Object invoke = method.invoke(new Target(),args);

                       System.out.println("调用目标方法后执行操作");
                       //目标方法返回值,返给给代理对象
                       return invoke;
                   }
                });

        //目标对象方法无返回值,代理也就没有。
        ti.method();
        System.out.println("-------------------");
        //代理对象的返回值,就是invoke方法的返回值。
        String method2 = ti.method2();
        System.out.println("method2:"+method2);
        System.out.println("-------------------");
        //代理对象调用方法,传入参数会传给invoke方法中的args参数,通过args参数可以传给目标方法的参数。
        int method3 = ti.method3(100);
        System.out.println("method3:"+method3);
    }
}

目标类

public class Target implements TargerInterface {
    @Override
    public void method() {
        System.out.println("method");
    }

    @Override
    public String method2() {
        System.out.println("method2");
        return "且随疾风前行身后亦需留心";
    }

    @Override
    public int method3(int i) {
        System.out.println("method3");
        return i;
    }
}

代理和目标都要实现的接口

public interface TargerInterface {
    public abstract void method();

    public abstract String method2();

    public abstract int method3(int i);
}

结果:

调用目标方法前执行操作
method
调用目标方法后执行操作
-------------------
调用目标方法前执行操作
method2
调用目标方法后执行操作
method2:且随疾风前行身后亦需留心
-------------------
调用目标方法前执行操作
method3
调用目标方法后执行操作
method3:100
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值