java 动态代理的原理举例

需要先理解反射的原理,类加载的原理

基于jdk1.8,理解了反射和动态代理就方便去理解一些框架大致的实现原理。

package com.demo;

/**
 * @fileName: ProxyTest
 * @description: 动态代理的举例
 * @author: PGUY43
 * @create: 2020-06-15 19:56
 **/


import javafx.scene.DepthTest;

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

/**
 * @Description: 代理类和被代理类都要实现的接口
 * @Author: PGUY43
 * @Date: 2020/6/15 20:00
 */
interface Animal {
     
    /**
    * @Description: deTest jdk1.8 接口可以新增默认方法和静态方法
    * @Param: []
    * @return: void
    * @Author: PGUY43
    * @Date: 2020/6/15 21:23
    */
    default void deTest(){
     
        System.out.println("这里是接口默认方法!");
    }
    static void  stTest(){
     
        System.out.println("这里是接口静态方法!");
    }

    String getBody();

    void eat(String food);

}

/**
 * @Description: 被代理的类
 * @Author: PGUY43
 * @Date: 2020/6/15 20:02
 */
class Person implements Animal {
     
    @Override
    public void deTest() {
     
        System.out.println("这里是Person重写接口的默认类型的方法");
    }

    @Override
    public String getBody() {
     
        return "我有四肢!";
    }

    @Override
    public void eat(String food) {
     
        System.out.println("吃" + food);
    }
}

/**
 * @description: 动态代理工厂
 * 1.根据加载内存中的被代理类,动态的创建一个代理类及其对象
 * 2.当通过代理类的对象的调用方法时,动态的调用被代理类的方法
 * @author: PGUY43
 * @create: 2020/6/15 20:04
 **/
class ProxyFactory {
     
    /**
     * @Description: getProxyInstance 该方法实现,返回一个代理类的对象,解决1
     * @Param: [obj]
     * @return: java.lang.Object
     * @Author: PGUY43
     * @Date: 2020/6/15 20:13
     */
    public static Object getProxyInstance(Object obj) {
     

        //这里使用的jdk提供的生成一个代理类的方法
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new MyInvocationHandler(obj));
    }
}

/**
 * @description:代理类实现的接口的动作
 * @author: PGUY43
 * @create: 2020/6/15 20:35
 **/
class MyInvocationHandler implements InvocationHandler {
     
    private Object object; //赋值时也需要被代理的类

    public MyInvocationHandler(Object object) {
     
        this.object = object;
    }

    //当我们通过代理类的对象,调用方法时,就会自动调用该方法
    @Override//其实这里就是代理类的实现细节
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
     
        //假如说在这里假如一个其他的方法 这里就可以实现aop切面的原理
        //xxx.test();
        //代理类对象调用的方法,此方法也就是被代理的对象的方法
        return method.invoke(object, args); //方法内就是被代理的对象,args为被代理类的方法参数
    }
}

public class ProxyTest {
     

    public static void main(String[] args) {
     
        //个人理解:左边一定要用接口多态去接,因为代理类和被代理类实现的是同一个接口,这时候被代理类只能去调用代理类的一些接口实现的方法
        Animal proxyInstance = (Animal) ProxyFactory.getProxyInstance(new Person());
        proxyInstance.eat("老八小汉堡");
        proxyInstance.deTest();//重写的默认方法的调用
        Animal.stTest();//接口的静态方法的调用
        System.out.println(proxyInstance.getBody());
    }
}

执行结果:

吃老八小汉堡
这里是Person重写接口的默认类型的方法
这里是接口静态方法!
我有四肢!

Process finished with exit code 0

你可能感兴趣的:(JAVA基础,动态代理)