Java 动态代理 使用

文章目录

1. JDK

Java标准库提供了一种动态代理(Dynamic Proxy)的机制:可以在运行期动态创建某个interface的实例。

JDK动态代理必须提供接口才可代理

public interface HelloService {
    void sayHello1(String name);
    String sayHello2(String name);
}
public class HelloServiceImpl implements HelloService {

    @Override
    public void sayHello1(String name) {
        System.out.println("hello1 " + name);
    }

    @Override
    public String sayHello2(String name) {
        System.out.println("hello2 " + name);
        return  name;
    }
}

代理对象实现 InvocationHandler 方法,直接通过JDK提供的一个Proxy.newProxyInstance()创建了一个接口对象。

public class JdkProxy implements InvocationHandler {

    // 被代理对象
    private Object target = null;

    /**
     * 创建代理对象
     * @param target
     * @return
     */
    public Object bind(Object target) {
        this.target = target;
        // 参数为:target 类加载器;target 的方法;实现 InvocationHandler 接口的逻辑代理类,即当前类
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }

    /**
     * 代理对象调用方法
     * @param proxy 代理对象
     * @param method 方法
     * @param args 方法参数
     * @return 代理调用方法结果
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("代理前");
        // 调用方法,参数是target不是proxy,因为target中才有具体的方法实现,proxy中没有
        Object obj = method.invoke(target,args);
        System.out.println("代理后");
        return obj;
    }
}

JDK动态代理测试:

@Test
public void jdkProxyTest(){
    JdkProxy jdkProxy = new JdkProxy();
    // 创建代理对象
    HelloService proxy = (HelloService)jdkProxy.bind(new HelloServiceImpl());

    // 调用方法
    proxy.sayHello1("jdk1");
    String sayHello2Return = proxy.sayHello2("jdk2");
    System.out.println("sayHello2Return " + sayHello2Return);
}

测试结果:

代理前
hello1 jdk1
代理后
代理前
hello2 jdk2
代理后
sayHello2Return jdk2

2. CGLIB

CGLIB动态代理只需要非抽象类即可代理

public class HelloServiceImpl {

    public void sayHello1(String name) {
        System.out.println("hello1 " + name);
    }

    public String sayHello2(String name) {
        System.out.println("hello2 " + name);
        return  name;
    }
}

代理对象实现 MethodInterceptor 接口

public class CglibProxy implements MethodInterceptor {

    /**
     * 生成cglib代理对象
     * @param cls
     * @return
     */
    public Object getProxy(Class cls){
        // cglib 增强类对象
        Enhancer enhancer = new Enhancer();
        // 设置增强类型
        enhancer.setSuperclass(cls);
        // 定义代理逻辑对象,即实现 MethodInterceptor 接口的对象
        enhancer.setCallback(this);
        return enhancer.create();
    }

    /**
     * 代理逻辑方法
     * @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 {
        System.out.println("代理前");
        Object returnObj = methodProxy.invokeSuper(o, objects);
        System.out.println("代理后");
        return returnObj;
    }
}

CGLIB动态代理测试:

@Test
public void cglibProxyTest(){
    CglibProxy cglibProxy = new CglibProxy();
    HelloServiceImpl helloServiceImpl = (HelloServiceImpl) cglibProxy.getProxy(HelloServiceImpl.class);

    helloServiceImpl.sayHello1("cglib");
    String returnObj = helloServiceImpl.sayHello2("cglib");
    System.out.println(returnObj);
}

测试结果:

代理前
hello1 cglib
代理后
代理前
hello2 cglib
代理后
cglib

参考:
你真的完全了解Java动态代理吗?看这篇就够了
Java 动态代理详解
动态代理

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值