Java 动态代理

动态代理

前言

最近在复习一些java知识,想着将之前没有注意的知识记录下来。第一次写博客,如果有什么问题的话希望大家指出来,共同探讨。

正文

什么是动态代理

动态代理其实就是代理类是由动态生成的。如果需要被代理的类有很多的话,就不用去一个个写代理类,符合面向切面编程,aop就是由动态代理来实现的。

动态代理实现方法

JDK动态代理

JDK动态代理是由 java.lang.reflect 包下的 Proxy 类的 newProxyInstance 来实现的。

首先看下 newProxyInstance 的方法参数:

public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,
                                          InvocationHandler h)

第一个参数是一个类加载器,可以使用被代理类来获得这个参数;
第二个参数是一个Class类数组,其实就是被代理类的所有实现接口;
第三个参数是一个接口,需要我们实现这个接口类,并且代理方法都在这个接口类的 invoke 方法中来实现。

接下来看实现方法,首先我们先假设一个场景,我们需要出售手中的一台笔记本电脑,然后我们将电脑挂到闲鱼上去买,这是我们手中的电脑就是被代理的类,而闲鱼就是代理类,它可以做一些自己的操作。

实现代码:
1.被代理的类需要实现一个接口,接口代码如下:

TradingPlatform.java
//交易平台接口
public interface TradingPlatform {
    void productInfo();
}

2.被代理类:

PersonalTrading.java
//个人交易,实现交易平台这个接口
public class PersonalTrading implements TradingPlatform {
    public void productInfo() {
        System.out.println("我是个人卖家,我出手一台笔记本电脑");
    }
}

3.JDK动态代理实现:

public class JdkProxyTest {
    public static void main(String[] args) {
        final PersonalTrading personalTrading = new PersonalTrading();
        Object proxyInstance = Proxy.newProxyInstance(personalTrading.getClass().getClassLoader(), personalTrading.getClass().getInterfaces(),
                new InvocationHandler() {
                    //proxy:代理对象,也就是proxyInstance
                    //method:当前被代理对象执行的方法
                    //args:当前被代理对象执行方法的参数
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("我是闲鱼app");
                        Object o = method.invoke(personalTrading, args);
                        return o;
                    }
                });
        ((TradingPlatform)proxyInstance).productInfo();
    }
}

4.输出
Java 动态代理

cglib动态代理

cglib动态代理则是由 Enhancer.create 方法来实现的。

首先看下方法create的参数:

public static Object create(Class type, Callback callback)

第一个参数就是被代理类的class;
第二个参数则是一个回调函数,具体的代理方法都在里面实现

实现代码:

1.这是一个第三方类库,调用时需要引入依赖

pom.xml

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>2.1_2</version>
</dependency>

2.被代理类:

PersonalTrading.java

public class PersonalTrading {
    public void productInfo() {
        System.out.println("我是个人卖家,我出手一台笔记本电脑");
    }
}

3.cglib动态代理实现方法:

public class CglibProxyTest {
    public static void main(String[] args) {
        final PersonalTrading personalTrading = new PersonalTrading();
        Object proxyObject = Enhancer.create(personalTrading.getClass(), new InvocationHandler() {
        	//o:代理对象,也就是proxyObject
        	//method:当前被代理对象执行的方法
        	//objects:当前被代理对象执行方法的参数
            public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                System.out.println("我是闲鱼app");
                return method.invoke(personalTrading, objects);
            }
        });
        ((PersonalTrading)proxyObject).productInfo();
    }
}

4.输出:
Java 动态代理

JDK动态代理和cglib动态代理的区别

相信看了上面代码的小伙伴应该已经发现了,JDK动态代理被代理的类需要实现一个接口,而在cglib动态代理中则不需要这么做。

总结

第一篇博客写完了,收工

上一篇:代理模式


下一篇:Java中的原生动态代理和CGLIB动态代理的原理,我不信你全知道!