SpringAop概念
当前仅想着能用简单了解一下,后续再深入研究,如果文中出现错误,希望好心人评论指正。
AOP : 面向切面编程
AOP底层实现:基于JDK的动态代理和基于Cglib的动态代理
AOP 开发明确的事项
1. 需要编写的代码
1.1 编写核心业务代码 (目标类的目标方法)
1.2 编写切面类,切面类中有通知(增强功能方法)
1.3 在配置文件中,配置织入关系,即将哪些通知与哪些连接点进行结合
2.AOP 技术实现的内容
Spring框架监控切入点方法的执行。一旦监控到切入点方法被运行,使用代理机制,动态创建目标对象的代理对象,根据通知类别,在代理对象的对应位置,将通知对应的功能织入,完成完整的代码运行逻辑。
3.AOP底层使用哪种代理方式
在spring中,框架会根据目标是否实现了接口来决定采用哪种动态代理的方式。
*JDK 的动态代理: 针对实现了接口的类产生代理。
*CGlib 的动态代理:针对没有实现接口的类产生代理,应用的是底层的字节码增强的技术 生成当前类的子类对象
*CGlib 的动态代理:针对没有实现接口的类产生代理,应用的是底层的字节码增强的技术 生成当前类的子类对象
AOP术语
Tatget(目标):被增强的对象
Proxy(代理): 一个类被AOP织入增强后,就产生一个结果代理类
Joinpoint(连接点):指的是可以被拦截到的点,在Spring中这些点指的是方法,因为Spring只支持方法类型的连接点
*增删改查这些方法都可以增强,这些方法称为连接点
Pointcut(切入点):所谓的切入点是指我们要对哪些连接点进行拦截的定义
*只想对save方法进行增强,save方法被称为是切入点。
Advice(通知/增强):拦截后要做的事情,封装增强业务逻辑的方法
*对save方法要进行权限校验,权限校验的方法称为是通知。
Aspect(切面):就是切入点和通知的组合\结合
Weaving(织入) : 将Advice应用到Target的过程 是指把增强应用到目标对象来创建新的代理对象的过程。Spring采用动态代理织入,而Aspectj采用编译期织入和类装载期植入。
*将权限校验应用到UserDaoImpl的save方法的这个过程
CGLib动态代理实现原理:
利用ASM开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
CGLIB 动态代理 示例:
package com.zhan.proxy.cglib; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class ProxyTest { public static void main(String[] args) { //目标对象 final Target target = new Target(); //增强对象 final Advice advice = new Advice(); //返回值就是动态生成的对象 基于cglib //1.创建增强器 Enhancer enhancer = new Enhancer(); //2.设置父类(目标) enhancer.setSuperclass(Target.class); //3.设置回调 enhancer.setCallback(new MethodInterceptor() { public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { advice.before(); Object invoke = method.invoke(target, args); advice.afterReturing(); return invoke; } }); //4.创建代理对象 Target proxy = (Target) enhancer.create(); proxy.save(); } }
JDK动态代理实现原理
通过实现InvocationHandler接口创建自己的调用处理器;
通过为Proxy类指定ClassLoader对象和一组interface来创建动态代理;
通过反射机制获取动态代理类的构造函数,其唯一参数类型就是调用处理器接口类型;
通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数参入;
JDK动态代理是面向接口的代理模式,如果被代理目标没有接口那么Spring也无能为力,Spring通过Java的反射机制生产被代理接口的新的匿名实现类,重写了其中AOP的增强方法。
JDK动态代理示例:
package com.zhan.proxy.jdk; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class ProxyTest { public static void main(String[] args) { final Target target = new Target(); final Advice advice = new Advice(); TargetInterface proxy = (TargetInterface) Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { advice.before(); Object invoke = method.invoke(target, args); advice.afterReturing(); return invoke; } } ); proxy.save(); } }
Nice to see you all!