一、切面编程概述
Aspect Oriented Programming(AOP),面向切面编程,是一个比较热门的话题。AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。
什么是代理:代理(Proxy)是一种设计模式, 提供了对目标对象另外的访问方式,即通过代理访问目标对象。这样可以在目标对象实现的基础上,增强额外的功能操作。(扩展目标对象的功能)。
二、JDK静态代理和动态代理
JDK代理内容详细见 http://www.cnblogs.com/jiyukai/p/6958744.html
三、cglib代理
Cglib代理,也叫做子类代理。在内存中构建一个子类对象从而实现对目标对象功能的扩展。
(1)JDK的动态代理有一个限制,就是使用动态代理的对象必须实现一个或多个接口。如果想代理没有实现接口的类,就可以使用CGLIB实现。
(2)CGLIB是一个强大的高性能的代码生成包,它可以在运行期扩展Java类与实现Java接口。它广泛的被许多AOP的框架使用,例如Spring AOP和dynaop,为他们提供方法的interception(拦截)。
(3)CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类。不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。
Cglib子类代理Demo实现
(1) 需要引入cglib系列jar文件,但是spring的核心包中已经包括了cglib功能,所以直接引入spring-core-x.x.x.jar即可;
(2)引入功能包后,就可以在内存中动态构建子类;
(3)代理的类不能为final修饰;
(4)如果目标对象的方法为final/static, 那么将不会被拦截。
具体实现代码
1.业务实现类,即将被代理的目标对象
package com.jyk.spring.cglib; public class UserDao { public void cglibTest() { System.out.println("cglib代理执行方法"); } }
2. cglib代理工厂,必须实现MethodInterceptor接口
package com.jyk.spring.cglib; import java.lang.reflect.Method; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; /* * cglib子类代理工厂 * 必须实现MethodInterceptor接口 * 对UserDao在内存中动态构建一个子类对象 */ public class UserCglibProxy implements MethodInterceptor{ //维护目标对象 private Object target; public UserCglibProxy(Object target) { this.target = target; } /* * 给目标对象创建代理对象 */ public Object getProxyInstance() { //1、初始化工具类 Enhancer en = new Enhancer(); //2、设置父类 en.setSuperclass(target.getClass()); //3、设置回调函数,触发intercept方法 en.setCallback(this); //4、创建子类(即代理对象) return en.create(); } @Override public Object intercept(Object obj, Method method, Object[] arg2, MethodProxy proxy) throws Throwable { System.out.println("执行开始"); //执行目标对象的方法 Object returnValue = method.invoke(target, arg2); System.out.println("执行结束"); return returnValue; } }
3.执行结果,由打印出来的对象可以看到proxy已经不是原有UserDao,而是经过cglib代理生成的代理对象
结论:在Spring的AOP编程中,
如果加入容器的目标对象有实现接口,用JDK代理;如果目标对象没有实现接口,用Cglib代理;