面试笔记——JDK动态代理机制和CGLIB动态代理机制

一)JDK动态代理机制实现

使用步骤:

1)自定义一个接口

public interface HelloInterface {
    void sayHello(String message);
}

2)实现接口

public class HelloInterfaceImpl implements HelloInterface{
    @Override
    public void sayHello(String message) {
        System.out.println("message:"+message);
    }
}


3)实现 InvocationHandler 接口并重写invoke方法,并在invoke方法中调用原生方法

public class MyInvocationHandler implements InvocationHandler {
    private final Object target;
    public MyInvocationHandler(Object target) {
        this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("say hello before");
        method.invoke(target,args);
        System.out.println("say hello after");
        return null;
    }
}


4)通过 Proxy.newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) 方法创建代理对象;

public class TestProxy {
    public static void main (String args[]){
        HelloInterface helloInterface=new HelloInterfaceImpl();
        MyInvocationHandler myInvocationHandler=new MyInvocationHandler(helloInterface);
        HelloInterface helloInterfaceProxy=(HelloInterface) Proxy.newProxyInstance(helloInterface.getClass().getClassLoader(),helloInterface.getClass().getInterfaces(),myInvocationHandler);
        helloInterfaceProxy.sayHello("Hello world!");
    }
}

运行效果如下:

2)CGLIB动态代理机制

使用步骤:

1)自定义一个类;

public class HelloService {
    public String send(String message) {
        System.out.println("message:" + message);
        return message;
    }
}


2)实现MethodInterceptor接口并重写 intercept 方法,intercept 用于拦截增强被代理类的方法,和 JDK 动态代理中的 invoke 方法类似

public class MyMethodInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("say hello before");
        Object object = methodProxy.invokeSuper(o, args);
        System.out.println("say hello after");
        return object;
    }
}


3)通过 Enhancer 类的 create()创建代理类

public class TestCgLib {
    public static void main(String args[]){
        // 创建动态代理增强类
        Enhancer enhancer = new Enhancer();
        // 设置类加载器
        enhancer.setClassLoader(HelloService.class.getClassLoader());
        // 设置被代理类
        enhancer.setSuperclass(HelloService.class);
        // 设置方法拦截器
        enhancer.setCallback(new MyMethodInterceptor());
        // 创建代理类
        HelloService aliSmsService = (HelloService) enhancer.create();
        aliSmsService.send("Hello world!");
    }
}

因为CGLIB是一个开源项目,需要引入相关的jar包来使用

<dependency>
      <groupId>cglib</groupId>
      <artifactId>cglib</artifactId>
      <version>3.3.0</version>
    </dependency>

运行效果:

简单说明:

1)因为JDK 动态代理只能代理实现了接口的类,所以为了解决这个问题,我们可以用 CGLIB 动态代理机制来避免,CGLIB 可以代理未实现任何接口的类;

2)就二者效率来看JDK动态代理更优秀一些

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值