切面编程
代码地址:
orbit-hub/spring-boot-samples at master (github.com)https://github.com/orbit-hub/spring-boot-samples/tree/master
切面执行顺序
Spring5以后顺序就一切正常
正常:前置通知===目标方法===返回通知===后置通知
异常: 前置通知===目标方法===异常通知===后置通知
try{
前置通知
目标方法的执行
返回通知
}catch(){
异常通知
}finally{
后置通知
}
1、使用注解形式
-
定义注解
@Target({ ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {public String title() default "11";}
-
定义切面
@Aspect
@Component
public class LogAspect2 {/*** 处理请求前执行*/@Before(value = "@annotation(controllerLog)")public void boBefore(JoinPoint joinPoint, Log controllerLog) {System.out.println(controllerLog.title());String name = joinPoint.getSignature().getName();System.out.println("前置logStart()==>"+name+"....【args: "+ Arrays.asList(joinPoint.getArgs()) +"】");}/*** 处理完请求后执行** @param joinPoint 切点*/@AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult")public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult) {System.out.println(controllerLog.title());String name = joinPoint.getSignature().getName();System.out.println("返回logReturn()==>"+name+"....【args: "+ Arrays.asList(joinPoint.getArgs()) +"】【result: "+jsonResult+"】");}//后置通知@After(value = "@annotation(controllerLog)")public void logEnd(JoinPoint joinPoint, Log controllerLog){System.out.println(controllerLog.title());String name = joinPoint.getSignature().getName();System.out.println("后置logEnd()==>"+name+"....【args: "+ Arrays.asList(joinPoint.getArgs()) +"】");}/*** 拦截异常操作** @param joinPoint 切点* @param e 异常*/@AfterThrowing(value = "@annotation(controllerLog)", throwing = "e")public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e) {System.out.println(controllerLog.title());String name = joinPoint.getSignature().getName();System.out.println("异常logError()==>"+name+"....【args: "+ Arrays.asList(joinPoint.getArgs()) +"】【exception: "+e+"】");}}
-
定义目标
@Component
public class HelloService {@Logpublic String sayHello(String name){String result = "你好:"+name;System.out.println(result);int length = name.length();return result + "---" + length;}
}
-
配置类
@Configuration
@EnableAspectJAutoProxy
@ComponentScan("com.orbit.aop")
public class MainConfig {}
-
测试类
public class AnnotationMainTest {public static void main(String[] args) {ApplicationContext applicationContext =new AnnotationConfigApplicationContext(MainConfig.class);HelloService helloService = applicationContext.getBean(HelloService.class);helloService.sayHello("zhangsan");}}
-
没有异常
11
前置logStart()==>sayHello....【args: [zhangsan]】
你好:zhangsan
11
返回logReturn()==>sayHello....【args: [zhangsan]】【result: 你好:zhangsan---8】
11
后置logEnd()==>sayHello....【args: [zhangsan]】
-
有异常
11
前置logStart()==>sayHello....【args: [zhangsan]】
你好:zhangsan
11
异常logError()==>sayHello....【args: [zhangsan]】【exception: java.lang.ArithmeticException: / by zero】
11
后置logEnd()==>sayHello....【args: [zhangsan]】
Exception in thread "main" java.lang.ArithmeticException: / by zero
2、使用切入点表达式
切入点表达式语法
语法结构: execution([ 权限修饰符 ] [ 返回类型 ] [ 类全路径 ] [ 方法名称 ]([ 参数列表 ]) )
举例 :对 com.orbit.aop.service.HelloService类里面的 sayHello进行增强
execution(* com.orbit.aop.service.HelloService.sayHello(..))
-
定义切面
@Aspect //说明这是切面
@Component //切面也是容器中的组件
public class LogAspect {//前置通知 增强方法/增强器@Before("execution(* com.orbit.aop.service.HelloService.sayHello(..))")public void logStart(JoinPoint joinPoint){String name = joinPoint.getSignature().getName();System.out.println("前置logStart()==>"+name+"....【args: "+ Arrays.asList(joinPoint.getArgs()) +"】");}//返回通知@AfterReturning(value = "execution(* com.orbit.aop.service.HelloService.sayHello(..))",returning = "result")public void logReturn(JoinPoint joinPoint,Object result){String name = joinPoint.getSignature().getName();System.out.println("返回logReturn()==>"+name+"....【args: "+ Arrays.asList(joinPoint.getArgs()) +"】【result: "+result+"】");}//后置通知@After("execution(* com.orbit.aop.service.HelloService.sayHello(..))")public void logEnd(JoinPoint joinPoint){String name = joinPoint.getSignature().getName();System.out.println("后置logEnd()==>"+name+"....【args: "+ Arrays.asList(joinPoint.getArgs()) +"】");}//异常@AfterThrowing(value = "execution(* com.orbit.aop.service.HelloService.sayHello(..))",throwing = "e")public void logError(JoinPoint joinPoint,Exception e){String name = joinPoint.getSignature().getName();System.out.println("异常logError()==>"+name+"....【args: "+ Arrays.asList(joinPoint.getArgs()) +"】【exception: "+e+"】");}
}
没有异常
前置logStart()==>sayHello....【args: [zhangsan]】
你好:zhangsan
返回logReturn()==>sayHello....【args: [zhangsan]】【result: 你好:zhangsan---8】
后置logEnd()==>sayHello....【args: [zhangsan]】
有异常
前置logStart()==>sayHello....【args: [zhangsan]】
你好:zhangsan
异常logError()==>sayHello....【args: [zhangsan]】【exception: java.lang.ArithmeticException: / by zero】
后置logEnd()==>sayHello....【args: [zhangsan]】