Aop(二)基本用法
程序员文章站
2022-05-23 21:46:42
...
Aop的基本用法:
1 使用Aop解决日志处理问题:
Aop的配置有两种:
注解方式 和 xml方式
注解方式解决日志处理问题:
步骤:
1 jar包坐标的引入:
2 beans.xml 配置
添加命名空间
配置aop代理
编写代码:
package com.sun.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Component
/** 声明切面组件 */
@Aspect
public class LogCut {
/**定义切入点 匹配方法规则定义 * 匹配规则表达式含义 拦截 com.sun.service 包下 以及子包下 所有类
的所有方法 */
@Pointcut("execution (* com.sun.service..*.*(..))")
public void cut(){}
/** 声明前置通知 并将通知应用到定义的切入点上 * 目标泪方法执行前 执行该通知 */
@Before(value="cut()")
public void before(){
System.out.println("前置通知.....");
}
/**声明返回通知 并将通知应用到切入点上 * 目标类方法执行完毕执行该通知 */
@AfterReturning(value="cut()")
public void afterReturning(){
System.out.println("返回通知....");
}
/**声明最终通知 并将通知应用到切入点上 * 目标类方法执行过程中是否发生异常 均会执行该通知 相当于异常中的 finally */
@After(value="cut()")
public void after(){
System.out.println("最终通知....");
}
/** * 声明异常通知 并将通知应用到切入点上 * 目标类方法执行时发生异常 执行该通知 */
@AfterThrowing(value="cut()",throwing="e")
public void afterThrowing(Exception e){
System.out.println("异常通知....方法执行异常时执行:"+e);
}
/** * 声明环绕通知 并将通知应用到切入点上 * 方法执行前后 通过环绕通知定义相应处理 */
@Around(value="cut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("环绕前置...");
System.out.println("环绕通知");
//得到引用地址以及调用的方法
System.out.println(pjp.getTarget()+"-"+pjp.getSignature());
Object result=pjp.proceed();
System.out.println("环绕后置...");
return result;
}
}
所有的注解中 "value="均可省略 直接写成这样 @Around("cut()")
Aop 匹配方法规则表达式语言
Aop 切入点表达式简介
执行任意公共方法:
执行 com.xyz.service 包下任意类的任意方法
执行 com.xyz.service 包 以及子包下任意类的任意方法
xml配置:
<!-- aop 相关配置 -->
<aop:config>
<!-- aop 切面配置 -->
<aop:aspect ref="logCut">
<!-- 定义 aop 切入点 -->
<aop:pointcut expression="execution (* com.sun.service..*.*(..))" id="cut"/>
<!-- 配置前置通知 指定前置通知方法名 并引用切入点定义 -->
<aop:before method="before" pointcut-ref="cut"/>
<!-- 配置返回通知 指定返回通知方法名 并引用切入点定义 -->
<aop:after-returning`在这里插入代码片` method="afterReturning" pointcutref="cut"/>
<!-- 配置异常通知 指定异常通知方法名 并引用切入点定义 -->
<aop:after-throwing method="afterThrowing" throwing="e" pointcut-ref="cut"/>
<!-- 配置最终通知 指定最终通知方法名 并引用切入点定义 -->
<aop:after method="after" pointcut-ref="cut"/>
<!-- 配置环绕通知 指定环绕通知方法名 并引用切入点定义 -->
<aop:around method="around" pointcut-ref="cut"/>
</aop:aspect>
</aop:config>
定义bean
package com.sun.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
* Created by 陈明 on 2019/5/29.
*/
@Aspect //切面类
@Component
public class LogCut {
//拦截规则 拦截service下面所有的东西
@Pointcut("execution(* com.sun.service..*.*(..))")
public void cut(){};
@Before("cut()")
public void before(){
System.out.println("前置通知....");
}
@After("cut()")
public void After(){
System.out.println("After....");
}
@AfterThrowing(pointcut = "cut()",throwing = "e")
public void afterThrowing (Exception e){
System.out.println("afterThrowing...");
}
@Around("cut()")
//在执行切入的过程中 就执行了(pjp 可以获取正在执行的是哪个方法 哪个类 只有pjp可以获取到)
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("环绕前置...");
//地址和执行的是哪个方法
System.out.println(pjp.getTarget()+"--"+pjp.getSignature());
Object result=pjp.proceed();
System.out.println("环绕后置...");
return result;
}
@AfterReturning("cut()")
public void afterReturning(){
System.out.println("afterReturning...");
}
}