动态代理
前言
最近在复习一些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.输出
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.输出:
JDK动态代理和cglib动态代理的区别
相信看了上面代码的小伙伴应该已经发现了,JDK动态代理被代理的类需要实现一个接口,而在cglib动态代理中则不需要这么做。
总结
第一篇博客写完了,收工