标签:style blog http color io os 使用 java ar
代理:方法的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 }
代理类:
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 target 25 * 目标对象 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 @Override 40 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 }
CGLIB代理总结:
1, CGLIB可以生成目标类的子类,并重写父类非final修饰符的方法。
2, 要求类不能是final的,要拦截的方法要是非final、非static、非private的。
标签:style blog http color io os 使用 java ar
原文地址:http://www.cnblogs.com/muzhongjiang/p/3969766.html