zoukankan      html  css  js  c++  java
  • Java动态代理学习笔记

    静态代理

    首先定义一个接口,声明一个方法,代表一类抽象角色(房屋出租)

    //抽象角色,租房
    public interface Rent {
        public void rent();
    }
    

    房屋出租这个抽象角色,代表一类真实的角色,这里指房主

    //真实角色,房东,出租房子
    public class Host implements Rent{
        public void rent(){
            System.out.println("房屋出租");
        }
    }
    

    代理角色,中介,代理房主出租房屋

    //代理角色,中介
    public class Proxy implements Rent{
        private Host host;
    
        public Proxy() {
        }
    
        public Proxy(Host host) {
            this.host = host;
        }
    
        //租房
        public void rent(){
            seeHouse();
            host.rent();
            fare();
        }
    
        //收中介费
        private void fare() {
            System.out.println("收中介费");
        }
    
        //看房
        private void seeHouse() {
            System.out.println("带房客看房");
        }
    
    
    }
    

    客户通过中介租到房子

    //客户类,一般客户都会找代理
    public class Client {
        public static void main(String[] args) {
            //房东租房
            Host host = new Host();
            //中介帮助房东租房
            Proxy proxy = new Proxy(host);
    
            //找中介
            proxy.rent();
        }
    }
    

    动态代理

    动态代理代理接口Rent,即代理了一类抽象角色Rent,而不是上面静态代理中的真实角色host。内部通过反射机制,根据传入的真实角色host,动态生成对应的代理类。

    package invocationHandler_test;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    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);
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            seeHouse();
            //使用反射实现的
            Object result = method.invoke(rent, args);
            fare();
            return result;
        }
    
        //看房
        public void seeHouse(){
            System.out.println("带房客看房");
        }
    
        //收中介费
        public void fare(){
            System.out.println("收中介费");
        }
    }
    

    客户租房,传入host,动态的生成代理类进行代理

    package invocationHandler_test;
    
    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();
        }
    }
    

    动态代理和静态代理区别

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

    • 静态代理在编译时就已经实现,编译完成后代理类是一个实际的class文件
    • 动态代理是在运行时动态生成的,即编译完成后没有实际的class文件,而是在运行时动态生成类字节码,并加载到JVM中
      特点:
    • 动态代理对象不需要实现接口,但是要求目标对象必须实现接口,否则不能使用动态代理。(因为JDK代理需要用构造方法动态获取具体的接口信息,如果不实现接口的话,没法初始化)

    参考:
    https://mp.weixin.qq.com/s?__biz=Mzg2NTAzMTExNg==&mid=2247484130&idx=1&sn=73741a404f7736c02bcdf69f565fe094&scene=19#wechat_redirect
    https://segmentfault.com/a/1190000011291179

    日积月累,水滴石穿
  • 相关阅读:
    11->centos6 安装oracle
    centos7安装rlwrap
    ajax
    java获取时间戳
    idea主要设置大纲图
    ppycharm设置解释器版本号码
    JTA 深度历险
    学会数据库读写分离、分表分库——用Mycat,这一篇就够了!
    分库分表的几种常见玩法及如何解决跨库查询等问题
    深入浅出SOA
  • 原文地址:https://www.cnblogs.com/lonelyisland/p/14647373.html
Copyright © 2011-2022 走看看