java 代理详解

一,java 代理的作用 

     1,RPC 远程调用中,客户端的代理对象被序列化 流,通过https 协议发送到Server端,然后反序列化为”代理对象“ 。实现远程调用。?

            在客户端Client, RPC 给接口生成一个代理类,运行过程中实际绑定的是这个接口生成的代理类。这样在接口方法被调用的时候,它实际上是被生成代理类拦截到了,这样我们就可以在生成的代理类里面,加入远程调用逻辑。

     2,代理模式的使用

 

三,静态代理:

     需要代理对象和目标对象实现一样的接口。

优点:可以在不修改目标对象的前提下扩展目标对象的功能。

缺点:

  1. 冗余。代理对象要实现与目标对象一致的接口,会产生过多的代理类。
  2. 不易维护。一旦接口增加方法,目标对象与代理对象都要进行修改。

例子:

package com.proxy;

public interface IUserDao {  //共同的接口,定义了代理行为method
    public void save();
}
public class UserDao implements IUserDao{  //被代理对象

    @Override
    public void save() {
        System.out.println("保存数据");
    }
}

public class UserDaoProxy implements IUserDao{  // 静态代理类, 包含了“被代理对象” 的变量, 同时拥有了“被代理对象”的行为,而且可以额外增加行为
                                                //代理类和‘被代理对象’存在关联关系。
    private IUserDao target;
    public UserDaoProxy(IUserDao target) {
        this.target = target;
    }
    
    @Override
    public void save() {
        System.out.println("开启事务");   //扩展了额外功能
        target.save();
        System.out.println("提交事务");
    }
}

 

 

四,动态代理

   

   静态代理与动态代理的区别主要在:

  •   静态代理在编译时就已经实现
  •   动态代理是在运行时动态生成的,在运行时动态生成类字节码,并加载到JVM中

两种常见的动态代理方式:JDK原生动态代理和CGLIB动态代理。

 

例子;(以JDK 动态代理为例)

 

public interface IUserDao {   // 代理类和目标类的共同的接口
    public void save();
}

public class UserDao implements IUserDao{  //目标类(对象)

    @Override
    public void save() {
        System.out.println("保存数据");
    }
}


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyFactory {               //代理类 ,使用JDK内部代理框架, 生成目标类的对象,目标方法。

    private Object target;// 维护一个目标对象

    public ProxyFactory(Object target) {
        this.target = target;
    }

    // 为目标对象生成代理对象
    public Object getProxyInstance() {
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
                new InvocationHandler() {

                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("开启事务");

                        // 执行目标对象方法
                        Object returnValue = method.invoke(target, args);

                        System.out.println("提交事务");
                        return null;
                    }
                });
    }
}

 

 

posted @ 2022-06-09 20:11  gaussen126  阅读(741)  评论(0编辑  收藏  举报