代理模式-动态代理

原理:反射

场景: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);
    }
}
相关推荐
喜欢流萤吖~13 分钟前
服务间的依赖管理:微服务的协作之道
java·微服务
invicinble19 分钟前
Spring如何把bean注册到容器里
java·后端·spring
S1998_1997111609•X33 分钟前
MacOS/ˉsh(so.))os.apkair/AI
开发语言·网络·人工智能
SimpleLearingAI34 分钟前
C++虚函数详解
开发语言·c++
代码不加糖1 小时前
0基础搭建前后端分离项目:实现菜单与界面左右布局
java·前端·javascript·mysql·elementui·mybatis
希望永不加班1 小时前
SpringBoot 敏感数据脱敏(序列化层)
java·spring boot·后端·spring
Dxy12393102161 小时前
Python使用XPath定位元素:动态计算与函数调用
开发语言·python
希望永不加班1 小时前
SpringBoot 数据库索引优化:慢查询分析
java·数据库·spring boot·后端·spring
胡利光1 小时前
Harness Engineering 02|Repo Harness:让仓库对 Agent 可读
java·junit·单元测试
Evand J1 小时前
【MATLAB代码介绍】三种CT模型的IMM(交互式多模型)对目标高精度定位
开发语言·matlab·ct·imm·交互式多模型·多模型·转弯