SpringAop注解版1 - 四种通知

r囧r小猫 2023-07-03 02:53 46阅读 0赞

什么是Aop
aop被称为面向切面编程,使用动态代理的方式在执行前后或出现异常后做相关逻辑. aop 是oop的一种延续通过预编译方式和运行时期动态代理实现程序功能的一种技术,利用aop可以对业务逻辑的各个部分进行分离,从而使得业务逻辑部分之间的耦合度降低,提高程序的可重用性,同时提高代码的开发效率。在程序运行期间,不修改源码的对已有的方法进行增强。

SpringAOP五种通知类型

  1. @Before:在目标方法执行之前,前置通知
  2. @After:在目标方法的执行之后,后置通知
  3. @AfterThrowing:在目标方法执行出现异常的时候,异常通知
  4. @AfterReturning:在目标方法最终执行完毕之后,最终通知
  5. @Around :环绕通知,能在目标方法的前后,异常最终处都能进行通知操作。

SpringAop的关键词
通知方法:aop五中通知方法所在的类
切面类:通知方法所在的类为切面类
连接点:每一个目标执行方法(需要通知的方法)和每一个通知方法的关系
切入点:我们真正的需要执行日志的地方
切入点表达式或者连接线:通过表达式来确定通知方法通知哪个目标执行方法。

aop案例

  1. 先导入Maven依赖 或者 jar包

    1. <!--aop 需要的包-->
    2. <dependency>
    3. <groupId>org.springframework</groupId>
    4. <artifactId>spring-aspects</artifactId>
    5. <version>5.1.0.RELEASE</version>
    6. </dependency>
    7. <dependency>
    8. <groupId>org.aspectj</groupId>
    9. <artifactId>aspectjweaver</artifactId>
    10. <version>1.8.13</version>
    11. </dependency>
    12. <dependency>
    13. <groupId>aopalliance</groupId>
    14. <artifactId>aopalliance</artifactId>
    15. <version>1.0</version>
    16. </dependency>
  1. <!--spring 核心包-->
  2. <dependency>
  3. <groupId>org.springframework</groupId>
  4. <artifactId>spring-context</artifactId>
  5. <version>5.1.0.RELEASE</version>
  6. </dependency>
  7. <!-- 日志包-->
  8. <dependency>
  9. <groupId>commons-logging</groupId>
  10. <artifactId>commons-logging</artifactId>
  11. <version>1.1.1</version>
  12. </dependency>
  13. </dependencies>
  1. 编写目标对象

    接口
    @Component
    public interface Operation
    {

    1. // 加法
    2. double add(double i,double j);
    3. // 减法
    4. double subtract(double i,double j);
    5. // 乘法
    6. double mul(double i,double j);
    7. // 除法
    8. double div(double i,double j);

    }

  1. 实现类
  2. @Component
  3. public class OperationImpl implements Operation
  4. {
  5. @Override
  6. public double add(double i, double j)
  7. {
  8. return i+j;
  9. }
  10. @Override
  11. public double subtract(double i, double j)
  12. {
  13. return i-j;
  14. }
  15. @Override
  16. public double mul(double i, double j)
  17. {
  18. return i*j;
  19. }
  20. @Override
  21. public double div(double i, double j)
  22. {
  23. return i/j;
  24. }
  25. }
  1. 编写通知

    @Aspect //声明该类是一个切面类
    @Component
    public class OperationProxy
    {

    1. // execution切入点表达式 (访问修饰符 返回值类型 目标执行的方法)
    2. @Before("execution(public double com.stone.aopdome.operation.impl.OperationImpl.add(double,double))")
    3. public void logbefore(){
    4. System.out.println("我是前置通知");
    5. }
    6. @After("execution(public double com.stone.aopdome.operation.impl.OperationImpl.add(double,double))")
    7. public void logAfter(){
    8. System.out.println("我是后置通知");
    9. }
  1. @AfterThrowing("execution(public double com.stone.aopdome.operation.impl.OperationImpl.add(double,double))")
  2. public void logException(){
  3. System.out.println("我是异常通知");
  4. }
  5. @AfterReturning("execution(public double com.stone.aopdome.operation.impl.OperationImpl.add(double,double))")
  6. public void logFinal(){
  7. System.out.println("我是最终通知");
  8. }
  9. }
  1. 编写 xml

    <?xml version=”1.0” encoding=”UTF-8”?>

    1. <!-- 扫描com.stone.dome包下的所有注解 -->
    2. <context:component-scan base-package="com.stone.aopdome"/>
    3. <!-- 开启基于注解的aop 功能-->
    4. <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
  1. </beans>
  1. 测试

    public class SpringAopTest
    {

    1. private ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
    2. @Test
    3. public void testaop1(){
    4. Operation bean = ioc.getBean(Operation.class);
    5. double add = bean.add(12.0, 20.0);
    6. System.out.println(add);
    7. }

    }

结果
在这里插入图片描述

如何得到目标方法的参数
在通知方法的参数列表中添加JoinPoint,最终通知能得到返回值,异常通知能得到异常

实例代码

  1. @Aspect //声明该类是一个切面类
  2. @Component
  3. public class OperationProxy
  4. {
  5. // execution切入点表达式 (访问修饰符 返回值类型 目标执行的方法)
  6. @Before(value = "execution(public double com.stone.aopdome.operation.impl.OperationImpl.*(double,double))")
  7. public void logbefore(JoinPoint joinPoint){
  8. System.out.println("我是前置通知,目标方法名"+joinPoint.getSignature().getName()+
  9. "\t目标方法的参数个数"+joinPoint.getArgs().length+
  10. "\t参数列表 "+ Arrays.asList(joinPoint.getArgs())
  11. );
  12. }
  13. @After("execution(public double com.stone.aopdome.operation.impl.OperationImpl.*(double,double))")
  14. public void logAfter(JoinPoint joinPoint){
  15. System.out.println("我是后置通知,目标方法名"+joinPoint.getSignature().getName()+
  16. "\t目标方法的参数个数"+joinPoint.getArgs().length+
  17. "\t参数列表 "+ Arrays.asList(joinPoint.getArgs())
  18. );
  19. }
  20. @AfterThrowing(value = "execution(public double com.stone.aopdome.operation.impl.OperationImpl.*(double,double))",throwing = "e")
  21. public void logException(JoinPoint joinPoint,Exception e){
  22. System.out.println("我是异常通知,目标方法名"+joinPoint.getSignature().getName()+
  23. "\t目标方法的参数个数"+joinPoint.getArgs().length+
  24. "\t参数列表 "+ Arrays.asList(joinPoint.getArgs())+
  25. "\t目标异常 "+e
  26. );
  27. }
  28. @AfterReturning(value = "execution(public double com.stone.aopdome.operation.impl.OperationImpl.*(double,double))",returning = "result")
  29. public void logFinal(JoinPoint joinPoint,Object result){
  30. System.out.println("我是最置通知,目标方法名"+joinPoint.getSignature().getName()+
  31. "\t目标方法的参数个数"+joinPoint.getArgs().length+
  32. "\t参数列表 "+ Arrays.asList(joinPoint.getArgs())+
  33. "\t目标方法的返回值"+result
  34. );
  35. }
  36. }

测试代码

  1. @Test
  2. public void testaop1(){
  3. Operation bean = ioc.getBean(Operation.class);
  4. double add = bean.add(12.0, 20.0);
  5. // System.out.println(1/0 );
  6. System.out.println(add);
  7. }

运行结果
在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,46人围观)

还没有评论,来说两句吧...

相关阅读

    相关 SpringAop注解1 - 通知

    什么是Aop aop被称为面向切面编程,使用动态代理的方式在执行前后或出现异常后做相关逻辑. aop 是oop的一种延续通过预编译方式和运行时期动态代理实现程序功能的一种技

    相关 SpringAOP通知

    spring(AOP通知) 切面 切面是封装通用业务逻辑的组件,可以作用到其他组件上。是spring组件中的某个方法、无返回类型、参数类型与通知类型有关。 一个切