代理模式-动态代理

原理:反射

场景:AOP

一、类有接口-JDK代理

java 复制代码
interface PeoPle{
    void work();
    String eat(String food);
}

class Man implements PeoPle{

    @Override
    public void work() {
        System.out.println("I am work");
    }

    @Override
    public String eat(String food) {
        System.out.println("我喜欢吃"+ food);
        return food;
    }
}

class ManProxy implements InvocationHandler{
    private static Object object;

    public static Object getProxyInstance(Object obj) {
        object = obj;
        /**
         * newProxyInstance():此方法用于返回一个代理类的对象,
         * 第一个参数为被代理类的类加载器,
         * 第二个参数为被代理类所实现的接口,
         * 第三个参数是代理类 代理 被代理类 要执行的方法所在的类的实例(当我们通过代理类的对象,调用方法a时,会自动调用下面的invoke()方法)
         */
        return Proxy.newProxyInstance(object.getClass().getClassLoader(),
                object.getClass().getInterfaces(),new ManProxy());
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Exception {
        //JDK动态代理的增强方法
        handle();
        System.out.println("拦截方法"+method);
        System.out.println("方法参数:" + Arrays.toString(args));
        //我们可以在此方法 Object obj = method.invoke(targetObject,args);前后新增方法可以增强原方法
        return method.invoke(object,args);
    }
    private void handle(){
        //处理一些业务逻辑
        System.out.println("JDKProxy处理业务逻辑");
    }
}

public class JDKProxy{


    public static void main(String[] args) throws Exception{
        Man man = new Man();
        PeoPle proxyInstance = (PeoPle) ManProxy.getProxyInstance(man);
        String foods = proxyInstance.eat("foods");
    }
}

二、类无接口-CGLIB代理

java 复制代码
class Animal{
    public String eat(String food){
        return food;
    }
    public void call(String str){
        System.out.println("Animal is "+ str + " call");
    }
}

public class CGLBProxy implements MethodInterceptor {
    // CGlib需要代理的目标对象
    private Object targetObject;

    public Object createProxyObject(Class obj) throws Exception{
        this.targetObject = obj.newInstance();
        //1.工具类
        Enhancer enhancer = new Enhancer();
        //2.设置父类
        enhancer.setSuperclass(targetObject.getClass());
        //3.设置回调函数
        enhancer.setCallback(this);
        System.out.println("this -> "+this);

        //4.创建子类(代理对象)
        Object proxyObj = enhancer.create();

        return proxyObj;
    }

    @Override
    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("这是增强方法前......");
        System.out.println("获取拦截方法:" + method.getName());
        System.out.println("获取方法参数:" + Arrays.toString(args));
        System.out.println("MethodProxy:" + methodProxy);
        Object obj = method.invoke(targetObject, args);
        System.out.println("这是增强方法后......");
        //模拟一下新增部分业务逻辑
        handle();
        return obj;
    }
    private void handle(){
        //处理一些业务逻辑
        System.out.println("CGLibProxy处理业务逻辑");
    }

    public static void main(String[] args) throws Exception{
        Animal proxyObject = (Animal) new CGLBProxy().createProxyObject(Animal.class);
        proxyObject.call("miao miao");
        String food = proxyObject.eat("food");
        System.out.println(food);
    }
}
相关推荐
不想写bug呀27 分钟前
多线程案例——单例模式
java·开发语言·单例模式
心平愈三千疾1 小时前
通俗理解JVM细节-面试篇
java·jvm·数据库·面试
我不会写代码njdjnssj1 小时前
网络编程 TCP UDP
java·开发语言·jvm
第1缕阳光1 小时前
Java垃圾回收机制和三色标记算法
java·jvm
funnyZpC1 小时前
好用的文档工具👉smart-doc
java
一只叫煤球的猫2 小时前
🔥 同事混用@Transactional和TransactionTemplate被我怼了,三种事务管理到底怎么选?
java·spring boot·后端
李少兄9 天前
解决OSS存储桶未创建导致的XML错误
xml·开发语言·python
阿蒙Amon9 天前
《C#图解教程 第5版》深度推荐
开发语言·c#
学Linux的语莫9 天前
python基础语法
开发语言·python
暖馒9 天前
C#委托与事件的区别
开发语言·c#