JDK动态代理简单实现

 java中的动态代理分为两种

  •         JDK动态代理 只提供接口的代理,不支持类的代理 核心是InvocationHandler和Proxy,在InvocationHandler中通过反射调用目标类的代码。我们可以在其前后加上我们自己的业务。
  •         CGLIB动态代理 如果代理类没有实现InvocationHandler接口,会采用此方式。CGLIB是一个代码类库,可以在运行时动态指定一个类的子信息。覆盖其中的方法并在其中写我们的业务。

CGLIB实现

1.写一个类作为增强对象

/**
 * @className: UserService
 * @description: game接口
 * @date: 2022/07/23
 * @author: Sora33
 */
public class GameService {

    void playing() {
        System.out.println("游戏中……");
    }
    void eat() {
        System.out.println("吃饭中……");
    }

}

2.主方法进行测试

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * @className: CgLibTest
 * @description: CgLibTest
 * @date: 2022/07/23
 * @author: Sora33
 */
public class CgLibTest {

    private static Logger logger = LoggerFactory.getLogger(CgLibTest.class);

    public static void main(String[] args) {

        GameService gameService = new GameService();

        // 创建一个增强器类
        Enhancer enhancer = new Enhancer();
        // 设置父类,可以理解为我们增强的类
        enhancer.setSuperclass(GameService.class);
        // 设置callback属性
        enhancer.setCallback(new MethodInterceptor() {
            // 重写interceptor方法
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                boolean methodName = method.getName().equals("playing");
                if (methodName) {
                    // 如果是正在玩游戏就执行此逻辑
                    logger.info("正在检测状态");
                    methodProxy.invoke(gameService, objects);
                    logger.info("游戏结束");
                    return null;
                } else {
                    logger.info("正在检测状态");
                    methodProxy.invoke(gameService, objects);
                    logger.info("并没有玩游戏");
                    return null;
                }
            }
        });

        GameService game = (GameService)enhancer.create();
        game.playing();
        game.eat();
    }
}

3.执行结果

10:30:35.334 [main] INFO com.sora.CgLibTest - 正在检测状态
游戏中……
10:30:35.347 [main] INFO com.sora.CgLibTest - 游戏结束
10:30:35.347 [main] INFO com.sora.CgLibTest - 正在检测状态
吃饭中……
10:30:35.347 [main] INFO com.sora.CgLibTest - 并没有玩游戏

JDK实现

1.先建一个car的接口

public interface Car {
    void run();
}

2.然后是实现类

public class CarImpl implements Car {

    @Override
    public void run() {
        System.out.println("准备上高速");
    }
}

3.(关键)写一个类,实现InvocationHandler接口

invoke是执行接口中的方法。我们需要在前后加上我们自己的操作

public class MyInvokeTest implements InvocationHandler {

    private Object object;

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

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 前置操作
        System.out.println("车子正在启动");
        // 执行方法
        Object invoke = method.invoke(object, args);
        // 后置操作
        System.out.println("到达目的地");
        return invoke;
    }
}

 4. 写一个测试类进行测试

public class JDKTest {
    public static void main(String[] args) {
        // 创建car实现类对象
        CarImpl car = new CarImpl();

        // 创建InvocationHandler对象
        InvocationHandler invocationHandler = new MyInvokeTest(car);

        // 代理
        Car instance = (Car)Proxy.newProxyInstance(
                car.getClass().getClassLoader(), // 类加载器
                car.getClass().getInterfaces(), // 目标接口
                invocationHandler);     // 完成代理模式的处理器

        // 执行
        instance.run();
    }
}

 5.打印结果

车子正在启动
准备上高速
到达目的地

更多知识请移步个人博客:33sora.com

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值