JDK动态代理和Cglib的动态代理

最简单的是静态代理方法,即代理模式,这里就不多啰嗦了。。

重点说一下JDK的动态代理和Cglib的动态代理吧

先说JDK的,需要被代理的类需要有接口,否则无法实现

1package proxy.dynamic; 2 3public interface IBook { 4 void add(); 5} 6

实现接口的类如下

1package proxy.dynamic; 2 3public class Book implements IBook { 4 5 @Override 6 public void add() { 7 System.out.println("Add Method!"); 8 } 9 10 11 12}

创建一个代理类,需要实现一个接口InvocationHandler接口,里面有一个invoke方法需要实现

同时创建一个生成实例的方法

1package proxy.dynamic; 2 3import java.lang.reflect.InvocationHandler; 4import java.lang.reflect.Method; 5import java.lang.reflect.Proxy; 6 7public class BookProxy implements InvocationHandler{ 8 private Object target; 9 10 public Object bind(Object target) { 11 this.target = target; 12 return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);//这里需要接口 13 } 14 @Override 15 public Object invoke(Object proxy, Method method, Object[] args) 16 throws Throwable { 17 Object result=null; 18 System.out.println("Before"); 19 result=method.invoke(target, args);//执行方法 20 System.out.println("After"); 21 return result; 22 } 23 24 25 26 27}

接下来创建测试类

1package proxy.dynamic; 2 3public class Test { 4 5 /** 6  * @param args 7  */ 8 public static void main(String[] args) { 9 BookProxy bp = new BookProxy(); 10 IBook book = (IBook) bp.bind(new Book()); 11 book.add(); 12 13 } 14 15}

可以看到依次输出了Before,方法,After

下面说一下Cglib的代理,Cglib代理不需要原类实现接口,依赖Cglib和asm两个Jar包

需要代理的类如下

1package cglib.proxy; 2 3public class Book { 4 5 public void add() { 6 System.out.println("Add Method!"); 7 } 8}

创建一个代理类,实现MethodInterceptor接口,同时写一个生成实例的getInstance方法

1package cglib.proxy; 2 3import java.lang.reflect.Method; 4 5import net.sf.cglib.proxy.Enhancer; 6import net.sf.cglib.proxy.MethodInterceptor; 7import net.sf.cglib.proxy.MethodProxy; 8 9public class CglibProxy implements MethodInterceptor{ 10 private Object target; 11 public Object getInstance(Object target){ 12 this.target=target; 13 Enhancer enhancer = new Enhancer(); 14 enhancer.setSuperclass(this.target.getClass()); 15 enhancer.setCallback(this); 16 return enhancer.create(); 17 } 18 @Override 19 public Object intercept(Object obj, Method method, Object[] args, 20 MethodProxy proxy) throws Throwable { 21 22 System.out.println("Before"); 23 proxy.invokeSuper(obj, args); 24 System.out.println("After"); 25 return null; 26 } 27 28 29 30}

接下来就是简单测试一下

1package cglib.proxy; 2 3public class Test { 4 5 /** 6  * @param args 7  */ 8 public static void main(String[] args) { 9 CglibProxy proxy = new CglibProxy(); 10 Book book=(Book) proxy.getInstance(new Book()); 11 book.add(); 12 13 } 14 15}

运行效果一样的

简单总结一下,JDK动态代理,需要实现一个接口InvocationHandler,要求被代理的对象必须有一个接口

Cglib代理需要实现MethodInterceptor接口,不需要被代理的类必须有接口

性能方法,参考其他文章,说JDK代理适合多例模式,而单例模式Cglib更好一些,因为Cglib是用底层的字节码技术生成实例,耗费时间较长,性能不如JDK动态代理。(有待验证。。)

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

CGLIB介绍与原理(通过继承的动态代理)

一、什么是CGLIB?CGLIB是一个功能强大,高性能的代码生成包。它为没有实现接口的类提供代理,为JDK的动态代理提供了很好的补充。通常可以使用Java的动态代理创建代理,但当要代理的类没有实现接口或者为了更好的性能,CGLIB是一个好的选择。二、CGLIB原理CGLIB原理:动态生成一个要代理类的子类,子类重写要代理的类的所有不是final的

Spring的两种代理JDK和CGLIB的区别浅谈

一、原理区别:java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP 2、如果目标对象实现了接口,可以

KVM调整cpu和内存

一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid