当前位置:网站首页>动态代理学习

动态代理学习

2022-08-11 06:46:00 LiuJia111222333

动态代理和静态代理角色一样
动态代理的代理类是动态生成的,不是我们直接写好的
动态代理分为两大类:基本接口的动态代理,基本类的动态代理

三种方法实现动态代理:

  1. 基于接口---jdk动态代理
  2. 基于类:cglib
  3. java字节码实现:javassit

需要了解两个类:Proxy(代理类),InvocationHandler (调用处理程序)   

InvocationHandler

InvocationHandler 是代理实例的调用处理程序 实现的接口。

每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法。

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

参数解析:

proxy- 调用该方法的代理实例

method-Method对应于代理实例上调用的接口方法的实例。对象的声明类Method将是声明方法的接口,它可能是代理类继承方法的代理接口的超接口。

args- 包含在代理实例上的方法调用中传递的参数值的对象数组,或者null如果接口方法不接受任何参数。原始类型的参数被包装在适当的原始包装类的实例中,例如 java.lang.Integeror java.lang.Boolean

Proxy创建静态的代理类

     Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
                                          new Class<?>[] { Foo.class },
                                          handler);

参数解析:

loader- 定义代理类的类加载器

interfaces- 代理类要实现的接口列表

h- 将方法调用分派到的调用处理程序

 学习案例1:

Rent接口

//租房接口
public interface Rent {
    public void rent(); //租房
}

Host房东类

//房东实现租房接口,代表他要租房了
public class Host implements Rent {

    @Override
    public void rent() {
        System.out.println("房东需要出租房子了!");
    }
}

ProxyInvocationHandler 处理程序类 

//等我们会用这个类,自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler {
    //创建被代理的接口
    private Rent rent;

    public void setRent(Rent rent){
        this.rent = rent;
    }

    //生成得到的代理类
    public Object getProxy(){
        //创建个代理类
        return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(),this);
    }

    //处理代理实例,并返回结果,当执行接口是,系统会默认执行invoke处理程序
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        //执行房东出租房子
        Object result = method.invoke(rent, args);
        seeHouse();
        SignContract();
        return result;
    }

    //处理其他业务
    public void seeHouse(){
        System.out.println("中介带看房子");
    }
    //处理其他业务
    public void SignContract(){
        System.out.println("中介签合同");
    }
}

主类

public class Client {
    public static void main(String[] args) {
        //真实角色是房东,他需要找代理给她出租房子
        Host host = new Host();

        //代理角色暂时没有,于是需要我们创建
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        pih.setRent(host); //设置房东需要代理
        //已经创建房东要租房子的代理类了。
        Rent proxy = (Rent) pih.getProxy();
        //执行租房
        proxy.rent();
    }

}

学习案例2 -- 通用动态代理:

UserService接口

public interface UserService {
    void add();
    void update();
    void delete();
    void select();
}

UserServiceImpl实现类:

public class UserServiceImpl implements  UserService{
    @Override
    public void add() {
        System.out.println("使用了add方法 ");
    }

    @Override
    public void update() {
        System.out.println("使用了update方法 ");
    }

    @Override
    public void delete() {
        System.out.println("使用了delete方法 ");
    }

    @Override
    public void select() {
        System.out.println("使用了select方法 ");
    }
}
ProxyInvocationHandler类:
​
//创建个万能动态代理
//等我们会用这个类,自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler {
    //创建被代理的接口
    private Object target;

    public void setTarget(Object target) {
        this.target = target;
    }

    //生成得到的代理类
    public Object getProxy() {
        //创建个代理类
        return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }

    //处理代理实例,并返回结果,当执行接口是,系统会默认执行invoke处理程序
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        //动态的获取该方法的名字
        System.out.println("debug提示:"+"使用了"+method.getName()+"方法");
        //执行房东出租房子
        Object result = method.invoke(target, args);

        return result;
    }
}

​

主类:

public class Client {
    public static void main(String[] args) {
        //创建一个真实角色
        UserService userService = new UserServiceImpl();

        //生成一个代理绝色
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        pih.setTarget(userService);
        //创建代理类
        UserService proxy = (UserService) pih.getProxy();
        proxy.delete();//执行删除方法

    }

}

原网站

版权声明
本文为[LiuJia111222333]所创,转载请带上原文链接,感谢
https://blog.csdn.net/LiuJia20010827/article/details/125652332