spring学习笔记(16)——AOP之前后置通知

来源:互联网 发布:淘宝手机详情怎么设置 编辑:程序博客网 时间:2024/06/05 08:18

前置通知

本文接上一篇spring学习笔记(15)——AOP基础

为了更好的解决上次说的问题,我们使用AOP

先加入jar包
这里写图片描述

package com.zj.asceptj;public interface Calcultor {    int add(int a, int b);    int sub(int a, int b);}
package com.zj.asceptj;import org.springframework.stereotype.Component;@Componentpublic class CalcultorImpl implements Calcultor{    @Override    public int add(int a, int b) {        int result = a + b;        return result;    }    @Override    public int sub(int a, int b) {        int result = a - b;        return result;    }}

记得给是实现类加上注解,让IOC容器管理

我们现在的要求是,给计算器加上日志:
- 方法调用前,打印出日志
- 方法调用后,打印出日志

写一个日志切面

package com.zj.asceptj;import java.util.Arrays;import java.util.List;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.springframework.stereotype.Component;/** * 声明该类为切面: *    1.让IOC容器创建这个类的bean(@Component) *    2.声明为切面(@Aspect) */@Aspect@Componentpublic class LoggingAscept {    //声明这是一个前置通知    @Before("execution(public int com.zj.asceptj.Calcultor.add(int, int))")    public void beforeMethod(JoinPoint joinpoint){        //注意,JoinPoint来自org.aspectj.lang.JoinPoint,小心导错包        //方法名        String methodName = joinpoint.getSignature().getName();        //方法参数        List<Object> args = Arrays.asList(joinpoint.getArgs());        System.out.println("method "+methodName+" begin:"+args);    }}

JoinPoint 参数可以让我们访问到连接点的细节,如果不需要,可以不加

在spring配置文件中配置

<?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:aop="http://www.springframework.org/schema/aop"    xmlns:context="http://www.springframework.org/schema/context"    xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd        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-4.0.xsd">    <context:component-scan base-package="com.zj.asceptj"></context:component-scan>    <!-- 让aspectJ的注解起作用 -->    <aop:aspectj-autoproxy></aop:aspectj-autoproxy></beans>

main方法

package com.zj.asceptj;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Main {    public static void main(String[] args) {        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");        Calcultor calcultor = (Calcultor) ctx.getBean("calcultorImpl");        int result = calcultor.add(1, 2);        System.out.println(result);    }}

结果
这里写图片描述

还有一个问题,我们使用@Before("execution(public int com.zj.asceptj.Calcultor.add(int, int))") 声明了调用哪个方法,如果我们想调用所有方法时这个前置通知都能起作用,要怎么做呢?很简单

  • @Before("execution(* com.zj.asceptj.*.*(..))")
  • *号是一个占位符,表示任意字符,大家可以跟原来的写法对比一下

后置通知

后置通知跟前置通知的用法一模一样,只要把@Before改为@After即可

package com.zj.asceptj;import java.util.Arrays;import java.util.List;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.springframework.stereotype.Component;/** * 声明该类为切面: *    1.让IOC容器创建这个类的bean(@Component) *    2.声明为切面(@Aspect) */@Aspect@Componentpublic class LoggingAscept {    @Before("execution(* com.zj.asceptj.*.*(..))")    public void beforeMethod(JoinPoint joinpoint){        //注意,JoinPoint来自org.aspectj.lang.JoinPoint,小心导错包        //方法名        String methodName = joinpoint.getSignature().getName();        //方法参数        List<Object> args = Arrays.asList(joinpoint.getArgs());        System.out.println("method "+methodName+" begin:"+args);    }    @After("execution(* com.zj.asceptj.*.*(..))")    public void afterMethod(JoinPoint joinpoint){        //注意,JoinPoint来自org.aspectj.lang.JoinPoint,小心导错包        //方法名        String methodName = joinpoint.getSignature().getName();        //方法参数        List<Object> args = Arrays.asList(joinpoint.getArgs());        System.out.println("method "+methodName+" end:"+args);    }}
  • 注意,无论方法是否抛出异常,后置通知都会被执行
  • 后置通知不能得到目标方法的返回值,返回值需要在返回通知中才能得到
0 0
原创粉丝点击