Spring AOP
Spring AOP
主要概念
aspect(切面) 由通知、切点、组成,是个逻辑概念可以理解为以下概念的集合
pointcut(切点) 每个类都拥有多个连接点,可以理解为连接点的集合。
joinpoint(连接点),程序执行的特定位置,如某个方法调用等
weaving(织入) 将通知(advice)连接到具体连接点的过程
advice(通知) 是植入到目标类连接点商店一段代码。
通知种类
Before advice 前置通知 无论方法是否异常都会执行,因为是先执行的
After returning advice 后置通知
after throwing advice 异常通知
after finally advice 最终通知 无论目标方法是否异常都会执行
Around advice 环绕通知
通过调用ProceedingJoinPoint.proceed()可以在目标执行全过程中执行。
target: 目标对象
aop Proxy: 产生的代理新对象
Spring AOP 底层实现,是通过JDK动态代理或CGLib代理在运行实际在对象初始化阶段织入代码的。
代码实现
定义切面类
定义一个Aspect切面
增加 @Aspect接口
当然需要注意注入@Component
定义切点 pointcut
在哪些地方执行,采用@pointcut注解完成,如@Pointcut(public * comm.xxx.xxx..(…))
修饰符(可以不写,但不能用*) + 返回类型 + 哪些包下的类 + 哪些方法 + 方法参数 “*” 代表不限, “..” 两个点代表参数不限
定义 Advice 通知
通知的五种切点类型的注解@Befor @After @AfterReturing @AfterThrowing @Around 来完成切点的增强动作 如@Before(“myPointcut()”)
只有在Around(环绕通知时才可以用)proceedingJoinPoint,其他情况下使用会报错
JDK代理的使用
代理的原理很简单,就是我们调用一个类时通过它的代理类去调用,这个类可以在执行目标类的前后执行我们想织入的代码。
但我们没都手写一个代理类会非常复杂而且具有倾入性,所以我们可以采用JDK或CGLib的方法来进行代理。
dk中为实现代理提供了支持,主要用到2个类:
1 | java.lang.reflect.Proxy |
jdk自带的代理使用上面有个限制,只能为接口创建代理类,如果需要给具体的类创建代理类,需要用后面要说的cglib
Proxy
这是JDK动态代理中主要的可一个类。
getProxyClass
为指定接口黄健代理的Class对象
1
2
3
4public static Class<?> getProxyClass(ClassLoader loader,
Class<?>... interfaces)
// ClassLoader 类的加载器,由于需要创建一个新的类,这个新类会在这里被加载到MetaSpace中
// 返回的是一个类newProxyInstance
创建代理的实例对象
1
2
3public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)这个方法先为指定的接口创建代理类,然后会生成代理类的一个实例,最后一个参数比较特殊,是InvocationHandler类型的,这个是个借口如下:
1
2public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;上面方法会返回一个代理对象,当调用代理对象的任何方法的时候,会就被
InvocationHandler
接口的invoke
方法处理,所以主要代码需要卸载invoke
方法中,稍后会有案例细说。getInvocationHandler
获取代理对象的InvocationHandler对象
1
2public static InvocationHandler getInvocationHandler(Object proxy)
throws IllegalArgumentException*上面几个方法大家熟悉一下,下面我们来看创建代理具体的2种方式。
创建代理方式一
步骤
创建代理类
调用Proxy.getProxyClass方法获取代理类的Class对象
创建请求处理器
使用InvocationHandler接口创建代理类的处理器
创建代理对象
通过代理类和InvocationHandler创建代理对象
使用代理对象
上面已经创建好代理对象了,接着我们就可以使用代理对象了
案例
创建IService接口的代理对象
1 |
|
CGLB 动态代理
CGLib是Spring实现动态代理的工具类,许多Spring的
CGlib可以产生代理对象,创建一个代理类。
通常用法
使用CGLIB创建动态代理时会在target中创建一个代理对象