Spring框架总结(八)
二、Cglib代理
名词理解:
Cglib代理,也叫做子类代理。利用继承关系实现被代理类的功能扩展.
缺点:
(1)JDK的动态代理有一个限制,就是使用动态代理的对象必须实现一个或多个接口。
(2)如果想代理没有实现接口的类,就可以使用CGLIB实现。
(3)CGLIB是一个强大的高性能的代码生成包,它可以在运行期扩展Java类与实现Java接口。
它广泛的被许多AOP的框架使用,例如Spring AOP和dynaop,为他们提供方法的interception(拦截)。
(4)CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类。
不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。
Cglib子类代理:
1) 需要引入cglib – jar文件, 但是spring的核心包中已经包括了cglib功能,所以直接引入spring-core-3.2.5.jar即可。
2)引入功能包后,就可以在内存中动态构建子类
3)代理的类不能为final, 否则报错。
4) 目标对象的方法如果为final/static, 那么就不会被拦截,即不会执行目标对象额外的业务方法。
在Spring的AOP编程中,
如果加入容器的目标对象有实现接口,用JDK代理;
如果目标对象没有实现接口,用Cglib代理;
1、创建userdao
1 public class UserDao { 2 3 public void save() { 4 System.out.println("-----已经保存数据!!!------"); 5 } 6 7 }
2、创建代理
1 public class Cglib implements MethodInterceptor { 2 3 private Object cglib; 4 5 public Cglib(Object cglib) { 6 this.cglib = cglib; 7 } 8 9 public Object getInstanceObject() { 10 Enhancer enhancer = new Enhancer(); 11 enhancer.setSuperclass(cglib.getClass()); 12 enhancer.setCallback(this); 13 return enhancer.create(); 14 } 15 16 @Override 17 public Object intercept(Object object, Method method, Object[] aObjects, 18 MethodProxy proxy) throws Throwable { 19 System.out.println("***********开启事物*************"); 20 Object returnValue = method.invoke(cglib, aObjects); 21 System.out.println("***********关闭事物*************"); 22 return returnValue; 23 } 24 25 }
3、测试
public class TestCglib { @Test public void test() { // 目标对象 UserDao target = new UserDao(); // class cn.itcast.c_cglib.UserDao System.out.println(target.getClass()); // 代理对象 UserDao proxy = (UserDao) new Cglib(target).getInstanceObject(); // UserDao子类:class cn.itcast.c_cglib.UserDao$$EnhancerByCGLIB$$25d4aeab System.out.println(proxy.getClass()); // 执行代理对象的方法 proxy.save(); } }
十年磨一剑,一剑破万法