代理模式-动态代理

原理:反射

场景: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);
    }
}
相关推荐
小bo波13 小时前
Java Swing 图形用户界面实验 —— 从算术练习到游戏开发的完整实践
java·课程设计·gui·游戏开发·扫雷·swing
咖啡八杯14 小时前
GoF设计模式——备忘录模式
java·后端·spring·设计模式
SamDeepThinking1 天前
裁掉那个差程序员后,给你看团队里高手的代码:这个习惯,希望你有
java·后端·程序员
朕瞧着你甚好1 天前
技术雷达 & Java 集成评估报告 — Apache Tika 3.3.1
java·ai编程
MacroZheng1 天前
短短几天,暴涨2.8万Star!又一款编程神器开源!
java·人工智能·后端
SamDeepThinking1 天前
函数式编程:用BiFunction消除多类型分支的代码重复
java·后端·面试
Flittly2 天前
【AgentScope Java新手村系列】(16)从RAG到多路检索
java·spring boot·spring
小兔崽子去哪了2 天前
Java 生成二维码解决方案
java·后端
人活一口气2 天前
从JVM调优到MCP协议:Java全栈技术体系深度总结与企业级架构实践
java·spring boot
NE_STOP2 天前
Vibe Coding -- 完整项目案例实操
java