02-mybatis选修-动态代理

代理模式简介

在这里插入图片描述

代理模式是23种设计模式之一。设计模式是前人总结的,在软件开发过程遇到常用问题的解决方案,常见的设计模式有单例模式、工厂模式、适配器模式等等。

代理模式的作用是在不修改原对象的基础上增强该对象的方法。比如官方购买苹果手机不赠送充电头,此时京东平台作为苹果的代理商,可以在代理销售苹果手机时赠送充电头。

代理模式分为静态代理、动态代理。静态代理会生成一个代理类,动态代理不会生成代理类,直接生成代理对象。

JDK动态代理

在这里插入图片描述

JDK动态代理是针对接口进行代理,所以我们要写被代理的接口和该接口的实现类。

package com.lxx.proxy;

//被代理接口
public interface Apple {
    //卖产品
    String sell(double price);

    //维修
    void repair();
}

package com.lxx.proxy;

// 被代理接口的实现类
public class AppleImpl implements Apple {
    @Override
    public String sell(double price) {
        System.out.println("商品卖了" + price + "元");
        return "iphone14";
    }

    @Override
    public void repair() {
        System.out.println("苹果售后维修");
    }
}

package com.lxx.proxy;

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

// 代理方式类,定义被代理方法的增强方式
// 该类实现InvocationHandler接口,重写invoke方法,定义方法的增强方式
public class ShoppingProxy implements InvocationHandler {
    //被代理对象
    private Apple apple;

    public ShoppingProxy(Apple apple) {
        this.apple = apple;
    }

    /*
     * 定义原方法的增强方式
     * @param proxy 被代理对象
     * @param method 被代理对象调用的方法
     * @param args 被代理对象调用的方法时,传入的参数
     * @return 方法的返回值
     * @throws Throwable
     */

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String name = method.getName(); //被代理对象执行的方法名
        if ("sell".equals(name)) {
            double price = (double) args[0] * 0.9; //增强参数
            Object result = method.invoke(apple, price);//执行方法
            return result + "和充电头"; //增强返回值
        } else if ("repair".equals(name)) {
            System.out.println("专属客服为您服务!");// 增强方法流程
            return method.invoke(apple, args);
        } else {
            return method.invoke(apple, args);// 什么都不增强
        }
    }
}

package com.lxx.proxy;

import java.lang.reflect.Proxy;

public class Test {
    public static void main(String[] args) {
        // 被代理对象
        Apple apple = new AppleImpl();
        // 代理方式对象
        ShoppingProxy shoppingProxy = new ShoppingProxy(apple);
        // 生成代理对象
        Apple appleJD = (Apple) Proxy.newProxyInstance(
                apple.getClass().getClassLoader(),// 类加载器
                apple.getClass().getInterfaces(),//被代理接口
                shoppingProxy);//代理方式对象
        // 执行增强后的方法
        String sell = appleJD.sell(100);
        System.out.println(sell);
        appleJD.repair();
    }
}

CGLib动态代理

在这里插入图片描述

CGLib动态代理简化了JDK动态代理的写法,JDK是针对接口代理,而CGLib是针对类代理。

        <!-- 引入cglib依赖 -->
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.3.0</version>
        </dependency>
package com.lxx.proxy2;

//被代理类
public class Apple {

    //卖产品
    public String sell(double price) {
        System.out.println("商品卖了" + price + "元");
        return "iphone14";
    }

    //维修
    public void repair() {
        System.out.println("苹果售后维修");
    }
}

package com.lxx.proxy2;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

// 代理方式类,实现MethodInterceptor接口,重写intercept方法
public class ShoppingProxy implements MethodInterceptor {
    private Apple apple; // 被代理对象

    public ShoppingProxy(Apple apple) {
        this.apple = apple;
    }

    /**
     * 定义原方法的增强方式
     * @param o 被代理对象
     * @param method 被代理对象调用的方法
     * @param objects 被代理对象调用的方法时,传入的参数
     * @param methodProxy 底层生成的代理类的引用
     * @return 方法的返回值
     * @throws Throwable
     */

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        String name = method.getName(); //被代理对象执行的方法名
        if ("sell".equals(name)) {
            double price = (double) objects[0] * 0.9; //增强参数
            Object result = method.invoke(apple, price);//执行方法
            return result + "和数据线"; //增强返回值
        } else if ("repair".equals(name)) {
            System.out.println("淘宝专属客服为您服务!");// 增强方法流程
            return method.invoke(apple, objects);
        } else {
            return method.invoke(apple, objects);// 什么都不增强
        }
    }
}

package com.lxx.proxy2;


import net.sf.cglib.proxy.Enhancer;

public class Test {
    public static void main(String[] args) {
        // 被代理对象
        Apple apple = new Apple();
        // 代理方式对象
        ShoppingProxy shoppingProxy = new ShoppingProxy(apple);
        // 生成代理对象
        Apple appleTB = (Apple) Enhancer.create(Apple.class, shoppingProxy);
        // 执行增强后的方法
        String sell = appleTB.sell(100);
        System.out.println(sell);
        appleTB.repair();
    }
}

`

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值