深入理解Java中的代理(Proxy)

岁酱吖の 提交于 2020-01-19 04:32:31

目录

 

1.代理的概念

2.代理的类型

2.1 静态代理

2.2 动态代理

2.2.1 动态代理需要的要素

2.2.2 创建动态代理的步骤

2.2.3 动态代理示例

引用:


1.代理的概念

代理模式为其他对象提供了一种代理以控制对这个对象的访问,具体实现包括两大类:静态代理和动态代理。Java动态代理机制的出现使得Java开发人员只需要简单地指定一组接口及委托类对象便能动态地获得代理类,并且其所生成的代理类在将所有的方法调用分派到委托对象上反射执行的同时,还可以对方法进行增强,这也正是Spring AOP的实现基础。

2.代理的类型

代理分为静态代理和动态代理

静态代理:在程序运行前,由程序员创建或特定工具类自动生成源代码并对其编译生成.class文件。

动态代理:程序在运行时期动态生成的指定类型对象的行为。

2.1 静态代理

静态代理需要3个部分,接口(要执行的事情)、实现接口的对象、一个代理对象

//功能接口
public interface PersonInterface {

    public void printName();
}

//具体的对象
public class Person implements PersonInterface {

    private String name;
    private String tel;
    private int age;

    public Person(String name, String tel, int age) {
        this.name = name;
        this.tel = tel;
        this.age = age;
    }

    @Override
    public void printName() {
        System.out.println(getName());
    }


    public String getName() {
        return name;
    }

    public String getTel() {
        return tel;
    }

    public int getAge() {
        return age;
    }
}

//代理对象
public class PersonProxy implements PersonInterface {

    private PersonInterface person;

    public PersonProxy(PersonInterface person) {
        this.person = person;
    }

    @Override
    public void printName() {
        System.out.println("每一个person类都应该输出其名字");
        person.printName();
    }
}

//测试方法
public class StaticProxyTest {

    public static void main(String[] args) {
        Person person = new Person("李白","188888822888",99);
        PersonProxy proxy = new PersonProxy(person);
        proxy.printName();
    }
}

输出结果:

2.2 动态代理

2.2.1 动态代理需要的要素

功能接口(interface)、实体对象、Proxy类(用来动态生成代理类)、程序调用处理器(InvocationHandler)

接口和实体对象上面已经介绍过,下面介绍下新朋友

 

java.lang.reflect.Proxy 1.3
static Class<?> getProxyClass(ClassLoader  loader,Class<?>...   interfaces)       返回一个实现了给定接口的代理类 

static  Object  newProxyInstance(ClassLoader  loader,Class<?>[]  interfaces,InvocationHandler handler)

返回一个实现了所有给定接口的代理类的实例对象,所有的方法都会通过给定的handler对象当中的invoke方法去执行

static boolean  isProxyClass(Class<?>  cl)   判断是否为一个代理对象

 

 

 

 

java.lang.reflect.InvocationHandler 1.3

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

定义此方法以包含每当代理对象上的方法被调用时要执行的操作

 

 

 

 

2.2.2 创建动态代理的步骤

  • 创建动态代理的接口(抽象类)和类
  • 创建实现了InvocationHandler接口的程序处理器类,对目标接口中的所有方法统一处理
  • 调用Proxy的静态方法newProxyInstance创建并生成相应的代理对象
  • 使用代理类

2.2.3 动态代理示例

创建接口和实体类

public interface PersonInterface {

    public void printName();
}

public class Person implements PersonInterface {

    private String name;
    private String tel;
    private int age;

    public Person(String name, String tel, int age) {
        this.name = name;
        this.tel = tel;
        this.age = age;
    }

    @Override
    public void printName() {
        System.out.println(getName());
    }


    public String getName() {
        return name;
    }

    public String getTel() {
        return tel;
    }

    public int getAge() {
        return age;
    }
}

创建调用程序处理器的类

public class TraceHandler implements InvocationHandler {

    private  Object target;

    public TraceHandler(Object obj) {
        this.target = obj;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.print(target);
        System.out.print("."+method.getName()+" (");
        if(args != null){
            for (int i=0; i< args.length; i++){
                System.out.println(args[i]);
                if(i<args.length-1){
                    System.out.print(", ");
                }
            }
        }
        System.out.println(")");

        return method.invoke(target,args);
    }
}

创建并使用代理

public class ProxieTest {

    public static void main(String[] args) {
        Person p = new Person("xueqi","18003526995",32);

        InvocationHandler handler = new TraceHandler(p);
        PersonInterface object = (PersonInterface) Proxy.newProxyInstance(PersonInterface.class.getClassLoader(),new Class[]{PersonInterface.class},handler);
        object.printName();
}

 

引用:

https://blog.csdn.net/justloveyou_/article/details/79407248

https://blog.csdn.net/vae1314chuanchen/article/details/87974728

https://blog.csdn.net/weixin_33919941/article/details/85670785

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!