首页 > 代码库 > cglib代理

cglib代理

代理:方法的interception(拦截)

1.JDK的动态代理有一个限制,就是使用动态代理的对象必须实现一个或多个接口。

 如果想代理没有实现接口的类,就可以使用CGLIB实现。

2.CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类。

 不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。

被代理类:

 1 package com.mzj.practice.test; 2 // 此类不能是final的,否则不能有子类,CGLIB也就不能工作了 3 public class UserServiceImpl { 4  5     // 这是final的方法,不能被子类重写,所以CGLIB不会拦截这个方法 6     public final void foo1() { 7         System.out.println(">> final的方法 <<"); 8     } 9 10     // 这是static的方法,CGLIB不会拦截这个方法11     public static void foo2() {12         System.out.println(">> static的方法 <<");13     }14 15     // 这是private的方法,CGLIB不会拦截这个方法16     private void foo3() {17         System.out.println(">> private的方法 <<");18     }19 20     // CGLIB会拦截这个方法,可以是public, protected, default的修饰符21     public void deleteUser() {22         System.out.println(">> 删除一个User <<");23     }24 }
View Code

代理类:

 1 package com.mzj.practice.test; 2  3 import java.lang.reflect.Method; 4  5 import net.sf.cglib.proxy.Enhancer; 6 import net.sf.cglib.proxy.MethodInterceptor; 7 import net.sf.cglib.proxy.MethodProxy; 8  9 /**10  * CGLIB代理类11  */12 public class LogCglibProxy {13     private Object target; // 代理的目标对象14 15     public LogCglibProxy(Object target) {16         super();17         this.target = target;18     }19 20     /**21      * 创建代理对象22      * 23      * @param <T>24      * @param target25      *            目标对象26      */27     public Object createProxyInstance() {28         Enhancer enhancer = new Enhancer(); // 该类用于生成代理对象29         enhancer.setSuperclass(target.getClass()); // 设置父类30         enhancer.setCallback(new MyInterceptor()); // 设置回调对象为自己这个对象31         return enhancer.create(); // 创建代理对象并返回32     }33 34     /**35      * 自定义 ——对代理方法的拦截后的操作36      */37     public class MyInterceptor implements MethodInterceptor {38 39         @Override40         public Object intercept(Object proxy, Method method, Object[] args,41                 MethodProxy methodProxy) throws Throwable {42             System.out.println(proxy.getClass());43             System.out.println("== Log:开始执行操作,方法名:" + method.getName() + " ==");44             Object result = methodProxy.invoke(target, args); // 执行原方法45             System.out.println("== Log:操作执行完毕 ==");46             return result;47         }48 49     }50 51     public static void main(String[] args) {52         LogCglibProxy proxy = new LogCglibProxy(new UserServiceImpl());53         UserServiceImpl us = (UserServiceImpl) proxy.createProxyInstance();54         us.deleteUser();55         us.foo1();56         us.foo2();57     }58 59 }
View Code

CGLIB代理总结:

1, CGLIB可以生成目标类的子类,并重写父类非final修饰符的方法。

2, 要求类不能是final的,要拦截的方法要是非final、非static、非private的。

cglib代理