Spring的AOP动态代理有两种实现方式,JDK实现和CGLIB实现,那么两者有何种区别呢?
JDK的动态代理主要是实现接口的方式,CGLIB主要是通过创建子类的方式,在父类的方法外进行操作。
如果类是接口的时候或者类是JDK创建的proxy类时使用的是JDK代理的非接口类使用CGLib代理,或者配置注解中proxyTargetClass = true两者的性能对比:

核心代码位置

JDK动态代理主要是通过,反射包中的Porxy类和InvokationHandler接口。它们结合在一起后可以创建动态代理类。Porxy类基于传递的参数创建动态代理类。InvokationHandler则用于激发动态代理类的方法。这个过程是在程序执行过程中动态生成与处理的,所以叫动态代理。
代码如下:
Porxy类提供了一个静态方法创建动态代理类。
public static Object newProxyInstance(ClassLoader loader,
Class>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
1、ClassLoader:ClassLoader会定义动态代理类,ClassLoader可以通过类或者接口获得,如果我们想通过接口获得,调用方法如下。
Task.class.getClassLoader()
如果通过类来获得,加入我们有一个类TaskImpl实现了Task接口,我们有个TaskImpl的对象ob,然后ClassLoader获取方法如下
ob.getClassLoader()
2、 Class>[] interfaces:动态代理类需要实现的接口
3、InvocationHandler:传递一个实现了InvokationHandler接口的类的实例
InvokationHandler是Java 反射包里面的一个接口。InvokationHandler通过用户类来实现,来激发一个动态代理类的方法。它只有一个方法:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
1、Object:实现方法的代理对象 2、Method:代理实例激发的方法,Porxy参数中的接口方法 3、Object[]:传递给方法的一系列参数
1、我们提供一个接口
package me.aihe;
public interface Task {
void setData(String data);
int getCalData(int x);
}
2、实现这个接口
package me.aihe;
public class TaskImpl implements Task {
@Override
public void setData(String data) {
System.out.println(data+ " Data is saved");
}
@Override
public int getCalData(int x) {
return x * 10;
}
}
3、定义自己的InvokationHandler类,并且实现InvokationHandler接口的Invoke方法
package me.aihe;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class MyInvokationHandler implements InvocationHandler {
private Object obj;
public MyInvokationHandler(Object object){
this.obj = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result;
if(method.getName().contains("get")){
System.out.println("...get Method Executing...");
}else{
System.out.println("...set Method Executing...");
}
result = method.invoke(obj, args);
return result;
}
}
4、创建一个工厂类获取动态代理类:
package me.aihe;
import java.lang.reflect.Proxy;
public class ProxyFactory {
public static Object newInstance(Object ob) {
return Proxy.newProxyInstance(ob.getClass().getClassLoader(),
new Class>[] { Task.class }, new MyInvokationHandler(ob));
}
}
5、提供我们的测试类
package me.aihe;
public class Test {
public static void main(String[] args) {
Task task = (Task)ProxyFactory.newInstance(new TaskImpl());
task.setData("Test");
System.out.println("============");
System.out.println(task.getCalData(5));
}
}
看到程序的输出结果:
...set Method Executing...
Test Data is saved
============
...get Method Executing...
50
这里提供下使用方式。
引入Maven:
cglib
cglib
3.3.0
package cglib.enhancer;
public class Hello {
public String sayHello(boolean throwException) throws Exception {
System.out.println("hello everyone!");
if(throwException)
throw new Exception("test exception");
return "123";
}
}
package cglib.enhancer;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class ProxyFactory implements MethodInterceptor {
//要代理的原始对象
private Object obj;
public Object createProxy(Object target) {
this.obj = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.obj.getClass());// 设置代理目标
enhancer.setCallback(this);// 设置回调
enhancer.setClassLoader(target.getClass().getClassLoader());
return enhancer.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
Object result = null;
try {
// 前置通知
before();
result = proxy.invokeSuper(obj, args);
// 后置通知
after();
} catch (Exception e) {
exception();
}finally{
beforeReturning();
}
return result;
}
private void before() {
System.out.println("before method invoke");
}
private void after() {
System.out.println("after method invoke");
}
private void exception() {
System.out.println("method invoke exception");
}
private void beforeReturning() {
System.out.println("before returning");
}
}
package cglib.enhancer;
public class EnhancerTest {
public static void main(String[] args) throws Exception {
Hello hello = new Hello();
ProxyFactory cglibProxy = new ProxyFactory();
Hello proxy = (Hello) cglibProxy.createProxy(hello);
String result=proxy.sayHello(true);
System.out.println(result);
}
}

版权声明:我们致力于保护作者版权,注重分享,被刊用文章【cglib动态代理(JDK)】因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!;
工作时间:8:00-18:00
客服电话
电子邮件
beimuxi@protonmail.com
扫码二维码
获取最新动态
