• Spring系列之:AOP


    一,相关名词

    切面(Aspect):一个横切功能的模块化,这个功能可能会横切多个对象(业务),比如:aMethod()方法就是一个"切面",它横切到多个业务中

    切入点(Pointcut):可以插入 "横切逻辑(如aMethod())"的方法。比如:"调用add()"就是一个切点。

    通知:

    前置通知(Before Advice):在切入点add()方法执行之前,插入的通知。

    后置通知(After Returning Advice):在切入点add()方法执行完毕之后,插入的通知

    异常通知(After Throwing Advice):在切入点add()方法抛出异常时,插入的通知

    最终通知(After FinallyAdvice):当切入点add()方法执行完毕时,插入的通知(不论是正常返回还是异常退出)

    环绕通知(Around Advice):可以贯穿切入点add()方法执行的整个过程。

    二,通知

    1,我们想把一个普通的类变成一个特定功能的类。有三种方法:

    继承类

    实现接口

    加注解

    配置

    2,把一个普通的类 变成 "通知",

    2.1,通过让类实现接口来实现

    通知类型          需要实现的接口         接口中的方法       执行时机

    前置通知  org.springframework.aop.MethodBeforeAdvice    before()       目标方法执行前      

    后置通知  org.springframework.aop.AfterReturningAdvice   afterReturning()    目标方法执行后

    异常通知  org.springframework.aop.ThrowsAdvice        无          目标方法发生异常时

    环绕通知  org.aopalliance.intercept.MethodInterceptor     invoke()    拦截对目标方法调用,即调用目标方法的整个过程

    2.2, 以后置通知为例:

    实现逻辑(三步):

      A,需要通知类  ---->  普通类实现接口

      B,业务类,业务方法  ------>  StudentServiceImpl中的addStudent();

      C,配置:

        将业务类,通知 纳入springIOC容器

        定义切入点(一端),定义通知类(另一类),通过pointcut-ref将两端连接起来

    代码实现:

    业务类:

    public class StudentServiceImpl implements StudentService{

      @Autowried

      private StudentDao studentDao;

      public int addStudent(Student student){

        int result = studentDao.insert(student);

        System.out.println("添加学生");

        return result;

      }

    }

    通知类:

    public class LogAfter implements AfterReturningAdvice{

       @Override

       public void afterReturning(Object returnValue,Method mehtod,Object[] args,Object target)throws Throwable{

          Sysout.out.println(" 前置通知 ");

          //我们还可以拿到目标对象的一些属性。对于studentService.addStudent(); 来说,studentService就是目标对象

          Sysout.println("目标对象:" + target + "调用的方法名:"+method.getName()+"方法参数的个数:"+args.length+",方法的返回值:"+ returnValue);

       }

    }

    配置:application.xml

    //将业务类纳入springIOC容器

    <bean id = "studentService" class = "org.yaming.service.StudentService">

      <property name = "stuentDao" ref = "studentDao"></property>

    </bean>

    //将通知纳入springIOC容器

    <bean id = "LogAfter" class = "org.yaming.aop.LogAfter"></bean>

    <aop:config>

      //切入点(连接线的一端:业务类的具体方法)

      <aop:pointcut expression = "execution(public * org.yaming.service.StudentServiceImpl.addStudent(..))"  id = "pointcut"/>

      //连接线的另一端:通知类

      <aop:advisor advice-ref = "LogAfter" pointcut-ref = "pointcut"/>

    </aop:config>

    3,通过注解来实现

    3.1,代码示例:

    @Aspect //声明该类是一个通知

    public class LogBeforeAnnotation(){

      @Before("execution(public * addStudent(..))")

      public void myBefore(){

        System.out.println("注解形式---前置通知")

      }

      @AfterReturning("execution(public * addStudent(..))")

      public void myAfter(){

        System.out.println("注解形式---后置通知")

      }

    }

    开启注解对AOP的支持: <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

    3.2,通过注解形式实现的aop,如果想获取目标对象的一些参数,需要使用一个对象:JoinPoint

    public class LogBeforeAnnotation(){

      @Before("execution(public * addStudent(..))")

      public void myBefore(JointPoint jp){

        System.out.println("注解形式---前置通知");

        System.out.println("目标对象:" + jp.getTarget()+",方法名:"+jp.getSignature().getName()+",参数列表:"+Arrays.toString(jp.getArgs()));

      }

      @AfterReturning("execution(public * addStudent(..))" , returning = "returningValue")

      public void myAfter(JoinPoint jp,Object returningValue){

        System.out.println("注解形式---后置通知");

        System.out.println("目标对象:" + jp.getTarget()+",方法名:"+jp.getSignature().getName()+",参数列表:"+Arrays.toString(jp.getArgs()) + ",返回值:"+returningValue);

      }

    }

  • 相关阅读:
    半夜的时候,干了个活,反了个小软件
    bzoj2243[SDOI2011]染色
    bzoj4034[HAOI2015]T2
    bzoj2661[BeiJing wc2012]连连看
    bzoj1406[AHOI2007]密码箱
    bzoj1452[JSOI2009]Count
    bzoj1934[Shoi2007]Vote 善意的投票
    bzoj1787[Ahoi2008]Meet 紧急集合&bzoj1832[AHOI2008]聚会
    bzoj1293[SCOI2009]生日礼物
    bzoj1221[HNOI2001] 软件开发
  • 原文地址:https://www.cnblogs.com/inspred/p/10827967.html
Copyright © 2020-2023  润新知