java动态代理

动态代理所执行的代理目的跟静态代理的代理目的相同的。
但动态代理的代理类是动态生成的,而不是提前配备的。
动态代理可以分为基于接口的动态和基于类的动态两种。

Proxy:生成动态代理实例
InvocationHandler:调用处理程序并返回结果

接口:

//吃这一行为的接口
public interface Eat {

    public void Eat();
}



真实对象:

//吃饭的人
public class Person implements Eat {
    @Override
    public void Eat() {
        System.out.println("吃晓汉堡");
    }
}



代理生成类:


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

//代理对象实现动态代理
public class ProxyHandler implements InvocationHandler {

    //被代理的接口
    private Eat eat;

    public void setEat(Eat eat) {
        this.eat = eat;
    }

    /**
     *  生成得到代理类
     *  第一个参数classLoader,为了知晓加载的类在什么位置
     *  第二个参数类的接口,要代理的接口
     *  第三个invocationHandler,自身
     */
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),eat.getClass().getInterfaces(),this);
    }


    //处理代理
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        cooking();
        //使用反射机制
        Object result = method.invoke(eat,args);
        clean();
        return result;
    }

    public void cooking(){
        System.out.println("制作晓汉堡");
    }
    public void clean(){
        System.out.println("洗碗");
    }

}



测试类:

public class TestEat {

    public static void main(String[] args) {
        //真实对象
        Person p = new Person();

        //生成代理类
        ProxyHandler proxyHandler = new ProxyHandler();
        //通过调用程序处理角色来处理调用的接口对象
        proxyHandler.setEat(p);

		//动态生成代理类
        Eat proxy = (Eat)proxyHandler.getProxy();
        proxy.Eat();
    }

}



结果:
java动态代理_第1张图片


当然,因为代理生成部分的代码大部分是固定的,因此可以单独抽离出来做一个工具类:

import com.spring.demo.Eat;

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

//代理对象实现动态代理
public class ToolProxy implements InvocationHandler {

    //被代理的接口
    private Object target;

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

    /**
     *  生成得到代理类
     *  第一个参数classLoader,为了知晓加载的类在什么位置
     *  第二个参数类的接口,要代理的接口
     *  第三个invocationHandler,自身
     */
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }


    //处理代理
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //使用反射机制
        Object result = method.invoke(target,args);
        return result;
    }


}





动态代理的优势(原图作者B站狂神说java):
java动态代理_第2张图片

你可能感兴趣的:(java相关,java)