zoukankan      html  css  js  c++  java
  • Java学习-JDK动态代理

    代理模式

    什么是代理模式?
    代理模式就是找一个中介帮你办一些事。你只需要关注自己的事就行了,其他的中介会帮你办好。

    代理模式中有三个要素:

    • 抽象对象:接口
    • 代理对象:类
    • 真实对象:类

    静态代理

    静态代理:有你自己来创建代理对象,每个真实对象都需要由你来创建代理对象。
    缺点:如果有很多个真实对象需要被代理,那你需要写很多的代理类。

    静态代理的主要思路就是:在代理类中放一个被代理类的对象,通过代理类去实现被代理类的方法。而在被代理方法执行之前或之后,你可以进行一些额外的操作。

    代码实现:

    interface Eat{
        void eat();
    }
    //真实类
    class Person implements Eat{
    
        private String name;
    
        Person(String name){
            this.name = name;
        }
        public String getName(){
            return this.name;
        }
    
        @Override
        public void eat() {
            System.out.println(this.name+"吃饭");
        }
    }
    //代理类
    class ProxyPerson implements Eat{
    
        private Person person;
    
        ProxyPerson(Person person){
            this.person = person;
        }
    
        @Override
        public void eat() {
            System.out.println("帮"+person.getName()+"做饭");
            person.eat();
            System.out.println("帮"+person.getName()+"洗碗");
        }
    }
    public class StaticProxyTest {
        public static void main(String[] args) {
            ProxyPerson pp = new ProxyPerson(new Person("小明"));
            pp.eat();
        }
    
    }
    

    运行结果:
    在这里插入图片描述

    这就是一个静态代理的例子。

    动态代理

    在静态代理中,代理类是固定的,而动态代理就是可以让代理类动态的生成。这里使用的反射机制。
    动态代理通过一个Proxy类和InvocationHandler接口来动态的创建代理类。

    代码实现:

    interface Eat{
        void eat();
    }
    //真实类
    class Person implements Eat{
    
        private String name;
    
        Person(String name){
            this.name = name;
        }
        public String getName(){
            return this.name;
        }
    
        @Override
        public void eat() {
            System.out.println(this.name+"吃饭");
        }
    }
    class MyInvocationHandler implements InvocationHandler{
    
        private Object obj;
    
        MyInvocationHandler(Object obj){
            this.obj = obj;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("做饭");
            method.invoke(obj);
            System.out.println("洗碗");
            return null;
        }
    }
    public class StaticProxyTest {
        public static void main(String[] args) {
            Eat person = new Person("tom");//真实对象
            InvocationHandler handler = new MyInvocationHandler(person);
            Eat eat = (Eat) Proxy.newProxyInstance(Person.class.getClassLoader(),Person.class.getInterfaces(),handler);
            eat.eat();
        }
    
    }
    
    

    运行结果:
    在这里插入图片描述

    动态代理实现步骤

    Proxy.newProxyInstance(Person.class.getClassLoader(),Person.class.getInterfaces(),handler);
    

    这句话主要是用来创建一个代理类的对象。
    在newProxyInstance这个方法中,先使用反射创建了一个代理类,代理类实现了Person所实现的接口。在代理类中还有一个带有InvocationHandler为参数的构造器,在调用代理对象的方法时,实际上调用的是InvocationHandler中的invoke方法。

    总结

    今天只是大概的了解一下静态代理和动态代理,对他们的底层实现还需要慢慢了解。

  • 相关阅读:
    将结构体存入Access数据库
    得到当前活动窗体的标题
    Scrapy各项命令说明
    session & viewstate
    网页设计中的默认字体样式详解
    ie6中href设为javascript:void(0)页面无法提交
    < ![if IE]> < ![endif]> 条件注释
    编译型与解释型、动态语言与静态语言、强类型语言与弱类型语言的区别
    Web字体的运用与前景
    jQuery和web.py美元符号($)冲突的解决方法
  • 原文地址:https://www.cnblogs.com/Z-Dey/p/12917630.html
Copyright © 2011-2022 走看看