SpringAop注解版1 - 四种通知

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

SpringAOP五种通知类型

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

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

aop案例

  1. 先导入Maven依赖 或者 jar包
 <dependencies>
        <!--aop 需要的包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.1.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.13</version>
        </dependency>

        <dependency>
            <groupId>aopalliance</groupId>
            <artifactId>aopalliance</artifactId>
            <version>1.0</version>
        </dependency>

        


        <!--spring 核心包-->

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.0.RELEASE</version>
        </dependency>

        <!-- 日志包-->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.1</version>
        </dependency>

    </dependencies>
  1. 编写目标对象
接口
@Component
public interface Operation
{
    //  加法
     double add(double i,double j);
    //  减法
     double subtract(double i,double j);
    //  乘法
     double mul(double i,double j);
    //  除法
      double div(double i,double j);
}


实现类
@Component
public class OperationImpl implements Operation
{
    @Override
    public double add(double i, double j)
    {
        return i+j;
    }

    @Override
    public double subtract(double i, double j)
    {
        return i-j;
    }

    @Override
    public double mul(double i, double j)
    {
        return i*j;
    }

    @Override
    public double div(double i, double j)
    {
        return i/j;
    }
}

  1. 编写通知
@Aspect  //声明该类是一个切面类
@Component
public class OperationProxy
{
    //   execution切入点表达式 (访问修饰符 返回值类型 目标执行的方法)
    @Before("execution(public double com.stone.aopdome.operation.impl.OperationImpl.add(double,double))")
    public void logbefore(){
        System.out.println("我是前置通知");
    }

    @After("execution(public double com.stone.aopdome.operation.impl.OperationImpl.add(double,double))")
    public void logAfter(){
        System.out.println("我是后置通知");
    }


    @AfterThrowing("execution(public double com.stone.aopdome.operation.impl.OperationImpl.add(double,double))")
    public void logException(){
        System.out.println("我是异常通知");
    }
    @AfterReturning("execution(public double com.stone.aopdome.operation.impl.OperationImpl.add(double,double))")
    public void logFinal(){
        System.out.println("我是最终通知");
    }
}

  1. 编写 xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- 扫描com.stone.dome包下的所有注解 -->
    <context:component-scan base-package="com.stone.aopdome"/>

    <!--    开启基于注解的aop 功能-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>


</beans>
  1. 测试
public class SpringAopTest
{
    private ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");

    @Test
    public void testaop1(){
        Operation bean = ioc.getBean(Operation.class);
        double add = bean.add(12.0, 20.0);
        System.out.println(add);

    }
}

结果
在这里插入图片描述

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

实例代码


@Aspect //声明该类是一个切面类
@Component
public class OperationProxy
{
    //   execution切入点表达式 (访问修饰符 返回值类型 目标执行的方法)
    @Before(value = "execution(public double com.stone.aopdome.operation.impl.OperationImpl.*(double,double))")
    public void logbefore(JoinPoint joinPoint){
        System.out.println("我是前置通知,目标方法名"+joinPoint.getSignature().getName()+
                "\t目标方法的参数个数"+joinPoint.getArgs().length+
                "\t参数列表 "+ Arrays.asList(joinPoint.getArgs())
                );
    }

    @After("execution(public double com.stone.aopdome.operation.impl.OperationImpl.*(double,double))")
    public void logAfter(JoinPoint joinPoint){
        System.out.println("我是后置通知,目标方法名"+joinPoint.getSignature().getName()+
                "\t目标方法的参数个数"+joinPoint.getArgs().length+
                "\t参数列表 "+ Arrays.asList(joinPoint.getArgs())
        );
    }


    @AfterThrowing(value = "execution(public double com.stone.aopdome.operation.impl.OperationImpl.*(double,double))",throwing = "e")
    public void logException(JoinPoint joinPoint,Exception e){
        System.out.println("我是异常通知,目标方法名"+joinPoint.getSignature().getName()+
                "\t目标方法的参数个数"+joinPoint.getArgs().length+
                "\t参数列表 "+ Arrays.asList(joinPoint.getArgs())+
                "\t目标异常 "+e
        );
    }
    @AfterReturning(value = "execution(public double com.stone.aopdome.operation.impl.OperationImpl.*(double,double))",returning = "result")
    public void logFinal(JoinPoint joinPoint,Object result){
        System.out.println("我是最置通知,目标方法名"+joinPoint.getSignature().getName()+
                "\t目标方法的参数个数"+joinPoint.getArgs().length+
                "\t参数列表 "+ Arrays.asList(joinPoint.getArgs())+
                "\t目标方法的返回值"+result
        );
    }
   }

测试代码

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

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值