目录

  • 1.引入pom依赖
  • 2.切入点表达式
    • ——组成
    • ——逻辑运算符
    • ——通配符
    • ——范例
  • 3. 启动类配置
  • 4.通知类型
    • 4.1 @Before : 标注当前方法作为前置通知
      • 4.1.1 创建自定义注解(用于使用注解作为切入点)
      • 4.1.2 设置切面类以及Before切面方法
      • 4.1.3 @Before : 标注当前方法作为前置通知测试
        • 4.1.3.1 Controller层
        • 4.1.3.2 service层
        • 4.1.3.3 serviceimpl层
        • @Before标注当前方法作为前置通知测试结果:
    • 4.2 @After : 标注当前方法作为后置通知
      • 4.2.1 创建自定义注解(用于使用注解作为切入点)
      • 4.2.2 设置切面类以及After切面方法
      • 4.2.3 @After : 标注当前方法作为后置通知测试
        • 4.2.3.1 Controller层
        • 4.2.3.2 service层
        • 4.2.3.3 serviceimpl层
        • @After : 标注当前方法作为后置通知 测试结果:
    • 4.3 @Around: 标注当前方法作为环绕通知
      • 4.3.1 设置切面类以及@Around切面方法
      • 4.3.2 @Around : 标注当前方法作为环绕通知测试
        • 4.3.2.1 Controller层
        • 4.3.2.2 service层
        • 4.3.2.3 serviceimpl层
        • @Around : 标注当前方法作为环绕通知 测试结果:
    • 4.4 @AfterReturning: 标注当前方法作为返回后通知
      • 4.4.1 设置切面类以及@AfterReturning切面方法
      • 4.4.2 @AfterReturning: 标注当前方法作为返回后通知测试
        • 4.4.2.1 Controller层
        • 4.4.2.2 service层
        • 4.4.2.3 serviceimpl层
        • @AfterReturning : 标注当前方法作为返回后通知 测试结果:
    • 4.5 @AfterThrowing: 标注当前方法作为抛出异常后通知
      • 4.5.1 设置切面类以及@AfterThrowing切面方法
      • 4.5.2 @AfterThrowing: 标注当前方法作为异常后通知测试
        • 4.5.2.1 Controller层
        • 4.5.2.2 service层
        • 4.5.2.3 serviceimpl层
        • @AfterThrowing: 标注当前方法作为异常后通知 测试结果:
  • 链接:[SpringBoot之AOP面向切面编程实例 源代码下载地址](https://download.csdn.net/download/JAVA_MHH/45633148)

1.引入pom依赖

  • 主要是spring-boot-starter-aop依赖—>里面有需要的切面注解等配置
<!--引入springboot父工程依赖--><!--引入依赖作用:可以省去version标签来获得一些合理的默认配置--><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.2.RELEASE</version></parent><dependencies><!--引入提供Web开发场景依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--引入面向切面依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency></dependencies>

2.切入点表达式

——组成

  • 关键字(访问修饰符 返回值 包名.类名.方法名(参数)异常名)
  • 示例:execution(public String com.it.Controller.findById(int))
组成部分 解释
关键字 描述表达式的匹配模式(参看关键字列表)
访问修饰符 方法的访问控制权限修饰符
类名 方法所在的类(此处可以配置接口名称)
异常 方法定义中指定抛出的异常

——逻辑运算符

运算符 解释
&& 连接两个切入点表达式,表示两个切入点表达式同时成立的匹配
|| 连接两个切入点表达式,表示两个切入点表达式成立任意一个的匹配
! 连接单个切入点表达式,表示该切入点表达式不成立的匹配

——通配符

*示例:execution(public * com.it.*.UserService.find*(*))
*解释:匹配com.it包下的任意包中的UserService类或接口中所有find开头的带有一个参数的方法

通配符 解释
* 单个独立的任意符号,可以独立出现,也可以作为前缀或者后缀的匹配符出现

  • 实例: execution(public User com..UserService.findById(..))
  • 解释: 匹配com包下的任意包中的UserService类或接口中所有名称为findById并且返回是User实体的方法
通配符 解释
.. 多个连续的任意符号,可以独立出现,常用于简化包名与参数的书写

  • 示例: execution(* *..*Service+.*(..))
  • 解释:匹配Service其子类方法
通配符 解释
+ 专用于匹配子类类型

——范例

  • execution(* *(…))
  • execution(* (…))
  • execution(* .*(…))
  • execution(public * .*(…))
  • execution(public int .*(…))
  • execution(public void .*(…))
  • execution(public void com….(…))
  • execution(public void com…service..(…))
  • execution(public void com.it.service..(…))
  • execution(public void com.it.service.User*.*(…))
  • execution(public void com.it.service.Service.(…))
  • execution(public void com.it.service.UserService.*(…))
  • execution(public User com.it.service.UserService.find*(…))
  • execution(public User com.it.service.UserService.*Id(…))
  • execution(public User com.it.service.UserService.findById(…))
  • execution(public User com.it.service.UserService.findById(int))
  • execution(public User com.it.service.UserService.findById(int,int))
  • execution(public User com.it.service.UserService.findById(int,*))
  • execution(public User com.it.service.UserService.findById(*,int))
  • execution(public User com.it.service.UserService.findById())
  • execution(List com.it.service.*Service+.findAll(…))

3. 启动类配置

  • 只需要注意下 其它的类都要在启动类同包或及下层目录即可 让@SpringBootApplication中@ComponentScan扫描到;
  • 如果类不在同级目录或下层目录 可以用@Import(Xxx.class)引入;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/** 面向切面编程Demo启动类* */
@SpringBootApplication
public class AOPTestApplication {public static void main(String[] args) {SpringApplication.run(AOPTestApplication.class, args);}
}

4.通知类型

4.1 @Before : 标注当前方法作为前置通知

  • 前置通知:原始方法执行前执行,如果通知中抛出异常,阻止原始方法运行
  • 应       用:数据校验

4.1.1 创建自定义注解(用于使用注解作为切入点)

  • 创建出名为BeforeDS 注解 作为后面的 before AOP切入点;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;/*** 自定义注解*/
@Retention(RetentionPolicy.RUNTIME)
public @interface BeforeDS {public String value() default "Before_Value";
}

4.1.2 设置切面类以及Before切面方法

  • @Aspect: 设置当前类为切面类
  • @Before("@annotation(com.it.mhh.anno.BeforeDS)")
           @Before:标注当前方法作为前置通知
           @annotation:指定用注解进行切面
           com.it.mhh.anno.BeforeDS:注解的全路径名
  • JoinPoint: 主要是获取切入点方法相应数据
          getSignature()): 是获取到这样的信息 :修饰符+ 包名+组件名(类名) +方法名
          joinPoint.getArgs() :这里返回的是切入点方法的参数列表这里返回的是切入点方法的参数列表
          (MethodSignature) joinPoint.getSignature().getMethod().getAnnotation(BeforeDS.class) :获取切入点方法上的@BeforeDS注解
          …

import com.it.mhh.anno.AfterDS;
import com.it.mhh.anno.BeforeDS;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;/*** 通过业务代码动态切换数据源* 识别执行方法上得注解*/
@Component
@Aspect //设置当前类为切面类
//设置order=0,执行时机优先于AbstractRoutingDataSource.determineCurrentLookupKey
@Order(0)
public class SwitchDSAspect {/*** 标注当前方法作为前置通知*/@Before("@annotation(com.it.mhh.anno.BeforeDS)")//用自定义注解 BeforeDS 作为切入点public void before(JoinPoint joinPoint) throws Throwable {Signature pointSignature = joinPoint.getSignature();System.err.println("切入点方法的修饰符+ 包名+组件名(类名) +方法名-->:"+pointSignature);Object[] args = joinPoint.getArgs();System.err.println("切入点方法的参数列表-->:"+ Arrays.toString(args));MethodSignature signature = (MethodSignature) joinPoint.getSignature();Method method = signature.getMethod();BeforeDS beforeDS = method.getAnnotation(BeforeDS.class);String value = beforeDS.value();//获取切入点方法上BeforeDS注解的值System.err.println("切面类中before方法--自定义注解BeforeDS中的值为-->:" + value);}}

4.1.3 @Before : 标注当前方法作为前置通知测试


4.1.3.1 Controller层

import com.it.mhh.anno.AfterDS;
import com.it.mhh.service.AOPTestService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("AOPtest")
public class AOPTestController {@Value("#{AOPTestServiceImpl}")private AOPTestService aopTestService;@RequestMapping("before")public String beforeTest() {System.out.println("before测试-controller");return aopTestService.beforeTest();}}

4.1.3.2 service层

public interface AOPTestService {String beforeTest();
}

4.1.3.3 serviceimpl层

import com.it.mhh.anno.BeforeDS;
import com.it.mhh.service.AOPTestService;
import org.springframework.stereotype.Service;@Service
public class AOPTestServiceImpl implements AOPTestService {@BeforeDS //使用自定义注解 执行切面@Overridepublic String beforeTest() {System.out.println("before测试-serviceimpl层");return "before测试end";}}

@Before标注当前方法作为前置通知测试结果:

  • 首先可以看出先走了controller层并打印了日志,我在serviceimp层的方法上加入了自定义注解, 此注解作为切入点那么就会走设置的切入点方法,执行完切入点方法后执行后面代码;
  • 此方法没有入参 所以参数列表为空;
  • BeforeDS注解没有设置值,所以是默认值



4.2 @After : 标注当前方法作为后置通知

  • 后置通知:原始方法执行后执行,无论原始方法中是否出现异常,都将执行通知
  • 应       用:现场清理

4.2.1 创建自定义注解(用于使用注解作为切入点)

  • 创建出名为AfterDS 注解 作为后面的 after AOP切入点;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/*** 自定义注解*/
@Retention(RetentionPolicy.RUNTIME)
public @interface AfterDS {public String value() default "After_Value";
}

4.2.2 设置切面类以及After切面方法

  • @Aspect: 设置当前类为切面类
  • @After("@annotation(afterDS)")
           @After:标注当前方法作为后置通知
           @annotation:指定用注解进行切面
           afterDS:切面方法上的入参注解名
  • JoinPoint: 主要是获取切入点方法相应数据
          getSignature()): 是获取到这样的信息 :修饰符+ 包名+组件名(类名) +方法名
          joinPoint.getArgs() :这里返回的是切入点方法的参数列表这里返回的是切入点方法的参数列表
          …

import com.it.mhh.anno.AfterDS;
import com.it.mhh.anno.BeforeDS;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;/*** 通过业务代码动态切换数据源* 识别执行方法上得注解*/
@Component
@Aspect //设置当前类为切面类
//设置order=0,执行时机优先于AbstractRoutingDataSource.determineCurrentLookupKey
@Order(0)
public class SwitchDSAspect {/** 标注当前方法作为后置通知* */@After("@annotation(afterDS)") //用自定义注解 AfterDS 作为切入点public void after(JoinPoint joinPoint, AfterDS afterDS) {Signature pointSignature = joinPoint.getSignature();System.err.println("切入点方法的修饰符+ 包名+组件名(类名) +方法名-->:" + pointSignature);Object[] args = joinPoint.getArgs();System.err.println("切入点方法的参数列表-->:" + Arrays.toString(args));String value = afterDS.value();System.err.println("切面类中after方法--自定义注解中的值为->" + value);}}

4.2.3 @After : 标注当前方法作为后置通知测试


4.2.3.1 Controller层

import com.it.mhh.anno.AfterDS;
import com.it.mhh.service.AOPTestService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("AOPtest")
public class AOPTestController {@Value("#{AOPTestServiceImpl}")private AOPTestService aopTestService;@AfterDS("afterController")@PostMapping("after/{name}")public String afterTest(@PathVariable("name") String name) {System.out.println("after测试-controller");return aopTestService.afterTest(name);}}

4.2.3.2 service层

public interface AOPTestService {String afterTest(String name);
}

4.2.3.3 serviceimpl层

import com.it.mhh.anno.BeforeDS;
import com.it.mhh.service.AOPTestService;
import org.springframework.stereotype.Service;@Service
public class AOPTestServiceImpl implements AOPTestService {@Overridepublic String afterTest(String name) {System.out.println("after测试-serviceimpl层");return "afterTest测试end--入参姓名-->:"+name;}}

@After : 标注当前方法作为后置通知 测试结果:

  • 首先可以看出在controller层的方法上加入了自定义注解@AfterDS(afterController),然后代码走了controller层并打印了日志,也走完了serviceimp层的方法以及打印了日志, 之后执行了切入点方法的代码;
  • 此方法有一个入参 所以参数列表中有一个值;
    @AlterDS()设置了value值 所以打印的就是设置的值



4.3 @Around: 标注当前方法作为环绕通知

  • 环绕通知:在原始方法执行前后均有对应执行执行,还可以阻止原始方法的执行
  • 应       用:十分强大,可以做任何事情

4.3.1 设置切面类以及@Around切面方法

  • @Aspect: 设置当前类为切面类
  • @Around(“pointCut()”)------>@Pointcut(value = “execution(public String com.it.mhh.service.impl.AOPTestServiceImpl.pointCutTest())”)
           @Around:标注当前方法作为环绕通知
           pointCut():自定义的方法,此方法上有一个注解 @Pointcut()
           @Pointcut():此注解的value值为切入点表达式
  • JoinPoint: 主要是获取切入点方法相应数据
          getSignature()): 是获取到这样的信息 :修饰符+ 包名+组件名(类名) +方法名
          joinPoint.getArgs() :这里返回的是切入点方法的参数列表这里返回的是切入点方法的参数列表
           ((MethodSignature) joinPoint.getSignature()).getMethod().getAnnotations():获取切入点方法上的所有注解
          …

import com.it.mhh.anno.AfterDS;
import com.it.mhh.anno.BeforeDS;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;/*** 通过业务代码动态切换数据源* 识别执行方法上得注解*/
@Component
@Aspect //设置当前类为切面类
//设置order=0,执行时机优先于AbstractRoutingDataSource.determineCurrentLookupKey
@Order(0)
public class SwitchDSAspect {//    @Pointcut(value = "@annotation(com.it.mhh.anno.DS)")@Pointcut(value = "execution(public String com.it.mhh.service.impl.AOPTestServiceImpl.pointCutTest())")public void pointCut() {}/**标注当前方法作为环绕通知* */@Around("pointCut()")public Object around(ProceedingJoinPoint joinPoint) throws Throwable {//获取执行签名信息Signature signature = joinPoint.getSignature();//通过签名获取执行类型(接口名)String targetClass = signature.getDeclaringTypeName();//通过签名获取执行操作名称(方法名)String targetMethod = signature.getName();//获取操作前系统时间beginTimelong beginTime = System.currentTimeMillis();//消息入参joinPoint.getArgs() 及执行结束 反参ret 之后return到请求页面System.err.println("环绕通知在此方法之前执行的代码");Object ret = joinPoint.proceed(joinPoint.getArgs());System.err.println("环绕通知在此方法之后执行的代码");//获取操作后系统时间endTimelong endTime = System.currentTimeMillis();System.err.println(targetClass + " 中 " + targetMethod + " 运行时长 " + (endTime - beginTime) + "ms");Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();Annotation[] annotations = method.getAnnotations();System.err.println("此方法上的所以注解:"+ Arrays.toString(annotations));System.err.println("真实反参--》"+ret);//这里可以修改返回数据return ret+"--》:通过环绕通知修改的参数";}}

4.3.2 @Around : 标注当前方法作为环绕通知测试


4.3.2.1 Controller层

import com.it.mhh.anno.AfterDS;
import com.it.mhh.service.AOPTestService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("AOPtest")
public class AOPTestController {@Value("#{AOPTestServiceImpl}")private AOPTestService aopTestService;@PostMapping("pointCut")public String pointCutTest() {System.out.println("pointCutTest测试-controller");return aopTestService.pointCutTest();}}

4.3.2.2 service层

public interface AOPTestService {String pointCutTest();
}

4.3.2.3 serviceimpl层

import com.it.mhh.anno.BeforeDS;
import com.it.mhh.service.AOPTestService;
import org.springframework.stereotype.Service;@Service
public class AOPTestServiceImpl implements AOPTestService {@Override@Orderpublic String pointCutTest() {System.out.println("pointCutTest测试-serviceimpl层");return "pointCutTest测试end";}}

@Around : 标注当前方法作为环绕通知 测试结果:

  • @Around环绕通知可以修改返回参数
  • 切入点为AOPTestServiceImpl类pointCutTest()方法
    所以首先走了controller并打印日志 然后到了pointCutTest()方法 在此方法之前走了环绕通知方法的joinPoint.proceed(joinPoint.getArgs())代码之前的编码,然后接着走AOPTestServiceImpl类pointCutTest()方法里的代码,走完后会回到环绕通知的代码并执行完后返回结束;
  • method.getAnnotations():这里 好像发现获取方法上的注解 获取不到@Override



4.4 @AfterReturning: 标注当前方法作为返回后通知

  • 返回后通知:原始方法正常执行完毕并返回结果后执行,如果原始方法中抛出异常,无法执行
  • 应       用:返回值相关数据处理

4.4.1 设置切面类以及@AfterReturning切面方法

  • @Aspect: 设置当前类为切面类
  • @AfterReturning(value = “execution(public String com.it.mhh.service.impl.AOPTestServiceImpl.afterReturningTest(int ,int ))”, returning = “result”)
           @AfterReturning:标注当前方法作为返回后通知
           execution:切入点表达式—匹配执行指定方法
           returning:设定使用通知方法参数接收返回值的变量名
  • JoinPoint: 主要是获取切入点方法相应数据
          getSignature()): 是获取到这样的信息 :修饰符+ 包名+组件名(类名) +方法名
          joinPoint.getArgs() :这里返回的是切入点方法的参数列表这里返回的是切入点方法的参数列表
           ((MethodSignature) joinPoint.getSignature()).getMethod().getAnnotations():获取切入点方法上的所有注解
          …

import com.it.mhh.anno.AfterDS;
import com.it.mhh.anno.BeforeDS;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;/*** 通过业务代码动态切换数据源* 识别执行方法上得注解*/
@Component
@Aspect //设置当前类为切面类
//设置order=0,执行时机优先于AbstractRoutingDataSource.determineCurrentLookupKey
@Order(0)
public class SwitchDSAspect {/**  标注当前方法作为返回后通知** 当连接点方法成功执行后,返回通知方法才会执行,如果连接点方法出现异常,则返回通知方法不执行。* 返回通知方法在目标方法执行成功后才会执行,所以,返回通知方法可以拿到目标方法(连接点方法)执行后的结果。* *///returning :设定使用通知方法参数接收返回值的变量名@AfterReturning(value = "execution(public String com.it.mhh.service.impl.AOPTestServiceImpl.afterReturningTest(int ,int ))", returning = "result")public void afterReturning(JoinPoint joinPoint, Object result) {Signature pointSignature = joinPoint.getSignature();System.err.println("切入点方法的修饰符+ 包名+组件名(类名) +方法名-->:" + pointSignature);Object[] args = joinPoint.getArgs();System.err.println("切入点方法的参数列表-->:" + Arrays.toString(args));System.err.println("切入点返回参-->:"+result);}
}

4.4.2 @AfterReturning: 标注当前方法作为返回后通知测试


4.4.2.1 Controller层

import com.it.mhh.anno.AfterDS;
import com.it.mhh.service.AOPTestService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("AOPtest")
public class AOPTestController {@Value("#{AOPTestServiceImpl}")private AOPTestService aopTestService;@PostMapping("afterReturning/{i1}/{i2}")public String afterReturningTest(@PathVariable("i1") int i1, @PathVariable("i2") int i2) {System.out.println("afterReturningTest测试-controller");return aopTestService.afterReturningTest(i1, i2);}}

4.4.2.2 service层

public interface AOPTestService {String afterReturningTest(int i1, int i2);
}

4.4.2.3 serviceimpl层

import com.it.mhh.anno.BeforeDS;
import com.it.mhh.service.AOPTestService;
import org.springframework.stereotype.Service;@Service
public class AOPTestServiceImpl implements AOPTestService {@Overridepublic String afterReturningTest(int i1, int i2) {System.out.println("afterReturningTest测试-serviceimpl层");return "afterReturningTest测试end--->int总和:" + (i1 + i2);}}

@AfterReturning : 标注当前方法作为返回后通知 测试结果:

  • 原始方法正常执行完毕并返回结果后执行,如果原始方法中抛出异常,无法执行
  • 切入点为AOPTestServiceImpl类afterReturningTest(int ,int )方法



4.5 @AfterThrowing: 标注当前方法作为抛出异常后通知

  • 抛出异常后通知:原始方法抛出异常后执行,如果原始方法没有抛出异常,无法执行
  • 应       用:对原始方法中出现的异常信息进行处理

4.5.1 设置切面类以及@AfterThrowing切面方法

  • @Aspect: 设置当前类为切面类
  • @AfterThrowing(value = “execution(public String com.it.mhh.service.impl.AOPTestServiceImpl.afterThrowingTest(String))”, throwing = “e”)
           @AfterThrowing:标注当前方法作为抛出异常后通知
           execution:切入点表达式—匹配执行指定方法
           throwing:设定使用通知方法参数接收原始方法中抛出的异常对象名
  • JoinPoint: 主要是获取切入点方法相应数据
          getSignature()): 是获取到这样的信息 :修饰符+ 包名+组件名(类名) +方法名
          joinPoint.getArgs() :这里返回的是切入点方法的参数列表这里返回的是切入点方法的参数列表
           ((MethodSignature) joinPoint.getSignature()).getMethod().getAnnotations():获取切入点方法上的所有注解
          …

import com.it.mhh.anno.AfterDS;
import com.it.mhh.anno.BeforeDS;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;/*** 通过业务代码动态切换数据源* 识别执行方法上得注解*/
@Component
@Aspect //设置当前类为切面类
//设置order=0,执行时机优先于AbstractRoutingDataSource.determineCurrentLookupKey
@Order(0)
public class SwitchDSAspect {/** 标注当前方法作为异常后通知* 异常通知方法只在连接点方法出现异常后才会执行,否则不执行。* 在异常通知方法中可以获取连接点方法出现的异常。在切面类中异常通知方法* *///throwing :设定使用通知方法参数接收原始方法中抛出的异常对象名@AfterThrowing(value = "execution(public String com.it.mhh.service.impl.AOPTestServiceImpl.afterThrowingTest(String))", throwing = "e")public void afterThrowing(JoinPoint joinPoint, Exception e) {Signature pointSignature = joinPoint.getSignature();System.err.println("切入点方法的修饰符+ 包名+组件名(类名) +方法名-->:" + pointSignature);Object[] args = joinPoint.getArgs();System.err.println("切入点方法的参数列表-->:" + Arrays.toString(args));System.err.println("切入点异常-->:" + e);}
}

4.5.2 @AfterThrowing: 标注当前方法作为异常后通知测试


4.5.2.1 Controller层

import com.it.mhh.anno.AfterDS;
import com.it.mhh.service.AOPTestService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("AOPtest")
public class AOPTestController {@Value("#{AOPTestServiceImpl}")private AOPTestService aopTestService;@PostMapping("afterThrowing/{string}")public String afterThrowingTest(@PathVariable("string") String string) {System.out.println("afterThrowingTest测试-controller");return aopTestService.afterThrowingTest(string);}}

4.5.2.2 service层

public interface AOPTestService {String afterThrowingTest(String string);
}

4.5.2.3 serviceimpl层

import com.it.mhh.anno.BeforeDS;
import com.it.mhh.service.AOPTestService;
import org.springframework.stereotype.Service;@Service
public class AOPTestServiceImpl implements AOPTestService {@Overridepublic String afterThrowingTest(String string) {System.out.println("afterThrowingTest测试-serviceimpl层");int i = 1 / 0;return "afterThrowingTest测试end--->String值:" + string;}}

@AfterThrowing: 标注当前方法作为异常后通知 测试结果:

  • 抛出异常后通知:原始方法抛出异常后执行,如果原始方法没有抛出异常,无法执行
  • 切入点为AOPTestServiceImpl类afterThrowingTest(String)方法



链接:SpringBoot之AOP面向切面编程实例 源代码下载地址

SpringBoot之AOP面向切面编程实例相关推荐

  1. SpringBoot之AOP面向切面编程

    什么是AOP AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开 ...

  2. Springboot 一文搞懂AOP面向切面编程

    Springboot AOP面向切面编程 AOP简介 AOP(Aspect Oriented Programming)面向切面编程,一种编程范式,指导开发者如何组织程序结构. 作用:在不惊动原始设计的 ...

  3. 切面是异步还是同步操作‘_Autofac的AOP面向切面编程研究

    什么是AOP: 我的理解是 把系统性的编程工作封装起来 =>我给这个取个名字叫 "Aspect",然后通过AOP技术把它切进我们的业务逻辑代码 => "业务& ...

  4. Autofac的AOP面向切面编程研究

    我的理解是 把系统性的编程工作封装起来 =>我给这个取个名字叫 "Aspect",然后通过AOP技术把它切进我们的业务逻辑代码 => "业务" 这样 ...

  5. Java绝地求生—Spring AOP面向切面编程

    Java绝地求生-Spring AOP面向切面编程 背景 动态代理 构建被代理对象 自动生成代理 调用动态代理 Spring方法 方式一:使用Spring的API接口 方式二:使用自定义类 方式三:使 ...

  6. java aop面向切面编程

    最近一直在学java的spring boot,一直没有弄明白aop面向切面编程是什么意思.看到一篇文章写得很清楚,终于弄明白了,原来跟python的装饰器一样的效果.http://www.cnblog ...

  7. 【AOP 面向切面编程】Android Studio 使用 AspectJ 监控方法运行原理分析

    文章目录 一.查看使用 AspectJ 后生成的 Class 字节码类 二.AspectJ 的本质 一.查看使用 AspectJ 后生成的 Class 字节码类 在 Android Studio 中查 ...

  8. 【AOP 面向切面编程】Android Studio 中配置 AspectJ ( 下载并配置AS中 jar 包 | 配置 Gradle 和 Gradle 插件版本 | 配置 Gradle 构建脚本 )

    文章目录 一.AspectJ 下载 二.拷贝 aspectjrt.jar 到 Android Studio 三.配置 Gradle 和 Gradle 插件版本 四.配置 Gradle 构建脚本 一.A ...

  9. 【AOP 面向切面编程】AOP 简介 ( AspectJ 简介 | AspectJ 下载 )

    文章目录 一.AOP 简介 二.AspectJ 简介 三.AspectJ 下载 一.AOP 简介 AOP 是 Aspect Oriented Programming 的缩写 , 面向切面编程 ; 利用 ...

最新文章

  1. 软考培训 - 上海2班开课剪影
  2. NR 5G 测量与寻呼
  3. net5:Theme主题样式的动态变换,在内容页content中操作影响模板页的操作
  4. 最好的电脑系统_热键被占用怎么办?电脑系统 程序 游戏热键被占用冲突如何解决?...
  5. ROS学习笔记-ROS语音识别与语音输出[2]
  6. Codeforces Round #700 (Div. 2) C. Searching Local Minimum 交互二分
  7. 前端学习(2635):vs 需要插件下载
  8. docker导入与导出容器
  9. 【转载】如何知道自己适合做什么
  10. jQuery hover事件鼠标滑过图片半透明标题文字滑动显示隐藏
  11. WP8.1学习系列(第二十三章)——到控件的数据绑定
  12. python中文件写入种类及功能方法
  13. 【Grafana】通过阿里云日志服务监控Nginx访问日志显示统计信息
  14. 2009 SD 2.0大会北京温都水城盛大召开(10月22日)
  15. 关于from scipy.misc import comb ImportError: cannot import name 'comb'的问题
  16. DVWA靶场——下载与安装(全)
  17. 运维笔试题1(转载)
  18. IBM developerWorks 技术主题 Linux 文档库
  19. 用python编写吃苹果小游戏
  20. 机器人与视觉,基于坐标系的运动偏移

热门文章

  1. vue 实现类似淘宝的商品详情页的商品展示
  2. win10 字体修改美化
  3. C#毕业设计——基于C#+asp.net+cs的CS应用程序平台多语种技术设计与实现(毕业论文+程序源码)——平台多语种技术
  4. MachineKey生成
  5. mac php mcrypt 安装,MacOSx下安装mcrypt
  6. linux内核 jiffies,Linux内核中的jiffies
  7. java南方公园电脑版_的平板电脑
  8. Android FILE_PROVIDER_PATHS 冲突错误 meta-data#android.support.FILE_PROVIDER_PATHS@resource
  9. 战地日记 第二篇 一月总结及一些感想
  10. 对金玺曾版《Unity3D手机游戏开发》第三章“第一人称射击游戏”修改,使支持僵尸连续攻击