Java的动态代理(代理模式)

Java的动态代理(代理模式)

  • 代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。

  • 代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。(如调用method.invoke()方法)

  • 代理模式最主要的就是有一个公共接口,一个具体的类,一个代理类,代理类持有具体类的实例,代为执行具体类实例方法。

动态代理的实现

  1. 创建一个与代理对象相关联的InvocationHandler
     InvocationHandler foodHandler = new FoodInvocationHandler<Food>(food);
    
  2. 使用Proxy类的getProxyClass静态方法生成一个动态代理类
    Class<?> foodProxyClass = Proxy.getProxyClass(Food.class.getClassLoader(), new Class<?>[] {Food.class});
    
  3. 获得动态代理类中一个带InvocationHandler参数的构造器constructor
    Constructor<?> constructor = foodProxyClass.getConstructor(InvocationHandler.class);
    
  4. 通过构造器constructor来创建一个动态实例foodProxy
    Food foodProxy = (Food) cons.newInstance(foodHandler);
    

自定义的FoodInvocationHandler类如下:

public class FoodInvocationHandler<T> implements InvocationHandler {
   //invocationHandler持有的被代理对象
    T target;
    
    public FoodInvocationHandler(T target) {
       this.target = target;
    }
    
    /**
     * proxy:代表动态代理对象
     * method:代表正在执行的方法
     * args:代表调用目标方法时传入的实参
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  
        //插入方法调用前的操作,如日志输出,计时等
        
        Object result = method.invoke(target, args);
        
        //插入方法调用后的操作

        return result;
    }
}

使用动态代理的例子:

public class ProxyTest {
    public static void main(String[] args) {
        
        //创建一个实例对象,这个对象是被代理的对象
        Food food = new Food("葡萄");
        
        //创建一个与代理对象相关联的InvocationHandler
        InvocationHandler foodHandler = new FoodInvocationHandler<Food>(food);
        
        //创建一个代理对象foodProxy来代理food,代理对象的每个执行方法都会替换执行Invocation中的invoke方法
        Food foodProxy = (Food) Proxy.newProxyInstance(Food.class.getClassLoader(), new Class<?>[]{Food.class}, foodHandler);

       //代理被代理类中的方法
        foodProxy.xxx();
    }
}

动态代理的进一步理解

生成代理类的构造方法,方法参数为InvocationHandler类型,看到这,而构造方法中则调用父类Proxy的构造方法。实际上,代理对象持有一个InvocationHandler对象,InvocationHandler对象持有一个被代理的对象,而在InvocationHandler的invoke方法中,通过调用传入的method参数的invoke方法实现调用被代理对象的方法,而method传入的对象就是InvocationHandler中的成员变量,即被代理类的对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值