zoukankan      html  css  js  c++  java
  • 基于XML配置的AOP实现日志打印

    Spring中可以使用注解或XML文件配置的方式实现AOP。
    1、导入jar包

    • com.springsource.net.sf.cglib -2.2.0.jar
    • com.springsource.org.aopalliance-1.0.0 .jar
    • com.springsource.org.aspectj.weaver-1.6.8 .RELEASE.jar
    • commons-logging-1.1.3. jar
    • spring-aop-4.0.0.RELEASE.jar
    • spring-aspects-4.0.0.RELEASE.jar
    • spring-beans-4.0.0.RELEASE.jar
    • spring-context-4.0.0.RELEASE.jar
    • spring-core-4.0.0.RELEASE.jar
    • spring-expression-4.0.0.RELEASE.jar

    aspectaop相关jar包 ---> 资源目录--->jar包资源--->AOP日志打印相关jar包(切面类) 

    Spring相关jar包 ---> 资源目录--->jar包资源--->Spring相关jar包 

    2、新建代理类和切面类

     1 @Component
     2 public class MathCalculator {
     3     public void add(int i, int j) {
     4         int result=i+j;
     5         System.out.println("目标方法add(int)执行了");
     6     }
     7     public void sub(int i, int j) {
     8         int result=i-j;
     9         System.out.println("目标方法sub执行了");
    10     }
    11     public void mult(int i, int j) {
    12         int result=i*j;
    13         System.out.println("目标方法mult执行了");
    14     }
    15     public void div(int i, int j) {
    16         int result=i/j;
    17         System.out.println("目标方法div执行了");
    18     }
    19 }
    MathCalculator

    切面类1:LogAspectp1:声明4中通知方法,Before、After、AfterThrowing、AfterReturning

     1 public class LogAspectp1{
     2     public void showBeginLog(JoinPoint jPoint){
     3         Object[] args = jPoint.getArgs();//获取方法参数
     4         List<Object> asList = Arrays.asList(args);//转化成List集合
     5         Signature signature = jPoint.getSignature();
     6         String name = signature.getName();//获取方法的名字
     7         System.out.println("LogAspectp1-----AOP日志开始");
     8         System.out.println("目标方法名:"+name+",参数列表:"+asList);
     9     }
    10     public void showAfterLog(){
    11         System.out.println("LogAspectp1-----AOP方法结束");
    12     }
    13     public void showExceptionLog(Exception ex){
    14         System.out.println("LogAspectp1-----AOP方法异常");
    15         System.out.println("异常信息:"+ex.getMessage());
    16     }
    17     public void showReturnLog(Object result){
    18         System.out.println("方法返回值:"+result);
    19         System.out.println("LogAspectp1-----AOP方法最终返回");
    20     }
    21 }

    切面类2:LogAspectp2:声明Around通知方法,代替前面的4中通知

     1 public class LogAspectp2{
     2     public Object showLog(ProceedingJoinPoint point){
     3         Object[] args = point.getArgs();
     4         List<Object> asList = Arrays.asList(args);
     5         Signature signature = point.getSignature();
     6         String name = signature.getName();
     7         Object result = null;
     8         try {
     9             try {
    10                 //目标方法之前要执行的操作,相当于@before
    11                 System.out.println("LogAspect2-----[环绕日志]"+name+"开始了,参数为:"+asList);
    12                 //调用目标方法
    13                 result = point.proceed(args);
    14             } finally {
    15                 //方法最终结束时执行的操作,相当于@after
    16                 System.out.println("LogAspect2-----[环绕日志]"+name+"结束了!");
    17             }
    18             //目标方法正常执行之后的操作,相当于@AfterReturning
    19             System.out.println("LogAspect2-----[环绕日志]"+name+"返回了,返回值为:"+result);
    20         } catch (Throwable e) {
    21             //目标方法抛出异常信息之后的操作,相当于@AfterThrowing
    22             System.out.println("LogAspect2-----[环绕日志]"+name+"出异常了,异常对象为:"+e);
    23             throw new RuntimeException(e.getMessage());
    24         }
    25         return result;
    26     }
    27 }

    3、在Spring的配置文件applicationContext.xml中进行配置

     1 <!-- 将需要加载到IOC容器中的bean配置好 -->
     2 <bean id="mathCalculator" class="com.bwlu.common.MathCalculator"></bean>
     3 <bean id="logAspectp1" class="com.bwlu.common.LogAspectp1"></bean>
     4 <bean id="logAspectp2" class="com.bwlu.common.LogAspectp2"></bean>
     5 <!-- 配置AOP,需要导入AOP名称空间 -->
     6 <aop:config>
     7     <!-- 声明切入点表达式 -->
     8     <aop:pointcut expression="execution(public * com.bwlu.aop.MathCalculatorImpl.*(..))" id="pointcut"/>
     9     <!-- 配置日志切面类,引用前面的类 ,通过order属性控制优先级-->
    10     <aop:aspect ref="logAspectp1" order="20">
    11         <!-- 通过method属性指定切面类的切面方法,通过pointcut-ref指定切入点表达式 -->
    12         <aop:before method="showBeginLog" pointcut-ref="pointcut"/>
    13         <aop:after method="showAfterLog" pointcut-ref="pointcut"/>
    14         <aop:after-throwing method="showExceptionLog" pointcut-ref="pointcut" throwing="ex"/>
    15         <aop:after-returning method="showReturnLog" pointcut-ref="pointcut" returning="result"/>
    16     </aop:aspect>
    17     <aop:aspect ref="logAspectp2" order="10">
    18         <aop:around method="showLog" pointcut-ref="pointcut"/>
    19     </aop:aspect>
    20 </aop:config>

    4、新建Junit测试类进行测试

     1 ApplicationContext ioc=new ClassPathXmlApplicationContext("applicationContext.xml");
     2 @Test
     3 public void test() {
     4     //需要进行强转,如果该类实现了一个接口(并且切入点表达式指向这个类),那么获取到的将不是该类的对象,需要强转
     5     //MathCalculatorImpl实现了MathCalculator接口,则
     6     //MathCalculator bean = (MathCalculator)ioc.getBean("mathCalculatorImpl");
     7     MathCalculator bean = (MathCalculator)ioc.getBean("mathCalculator");
     8     bean.add(10, 5);
     9     System.out.println();
    10     bean.add(10.0, 5);
    11     System.out.println();
    12     bean.sub(10, 5);
    13     System.out.println();
    14     bean.mult(10, 5);
    15     System.out.println();
    16     bean.div(10, 0);
    17 }

    运行结果:

     1 LogAspectp2-----[环绕日志]add开始了,参数为:[10, 5]
     2 LogAspectp1-----AOP日志开始
     3 目标方法名:add,参数列表:[10, 5]
     4 目标方法add(int)执行了
     5 LogAspectp1-----AOP方法结束
     6 方法返回值:null
     7 LogAspectp1-----AOP方法最终返回
     8 LogAspectp2-----[环绕日志]add结束了!
     9 LogAspectp2-----[环绕日志]add返回了,返回值为:null
    10 
    11 LogAspectp2-----[环绕日志]add开始了,参数为:[10.0, 5.0]
    12 LogAspectp1-----AOP日志开始
    13 目标方法名:add,参数列表:[10.0, 5.0]
    14 目标方法add(double)执行了
    15 LogAspectp1-----AOP方法结束
    16 方法返回值:15.0
    17 LogAspectp1-----AOP方法最终返回
    18 LogAspectp2-----[环绕日志]add结束了!
    19 LogAspectp2-----[环绕日志]add返回了,返回值为:15.0
    20 
    21 LogAspectp2-----[环绕日志]sub开始了,参数为:[10, 5]
    22 LogAspectp1-----AOP日志开始
    23 目标方法名:sub,参数列表:[10, 5]
    24 目标方法sub执行了
    25 LogAspectp1-----AOP方法结束
    26 方法返回值:null
    27 LogAspectp1-----AOP方法最终返回
    28 LogAspectp2-----[环绕日志]sub结束了!
    29 LogAspectp2-----[环绕日志]sub返回了,返回值为:null
    30 
    31 LogAspectp2-----[环绕日志]mult开始了,参数为:[10, 5]
    32 LogAspectp1-----AOP日志开始
    33 目标方法名:mult,参数列表:[10, 5]
    34 目标方法mult执行了
    35 LogAspectp1-----AOP方法结束
    36 方法返回值:null
    37 LogAspectp1-----AOP方法最终返回
    38 LogAspectp2-----[环绕日志]mult结束了!
    39 LogAspectp2-----[环绕日志]mult返回了,返回值为:null
    40 
    41 LogAspectp2-----[环绕日志]div开始了,参数为:[10, 0]
    42 LogAspectp1-----AOP日志开始
    43 目标方法名:div,参数列表:[10, 0]
    44 LogAspectp1-----AOP方法结束
    45 LogAspectp1-----AOP方法异常
    46 异常信息:/ by zero
    47 LogAspectp2-----[环绕日志]div结束了!
    48 LogAspectp2-----[环绕日志]div出异常了,异常对象为:java.lang.ArithmeticException: / by zero
    运行结果
  • 相关阅读:
    分布式缓存技术redis学习系列(一)——redis简介以及linux上的安装
    redis整合spring(redisTemplate工具类)
    架构之路之spring+redis的集成
    java之redis篇(spring-data-redis整合)
    Redis 安装
    java对redis的基本操作
    mybatis 详解(九)------ 一级缓存、二级缓存
    mybatis 详解(八)------ 懒加载
    mybatis 详解(七)------一对一、一对多、多对多
    mybatis 详解(六)------通过mapper接口加载映射文件
  • 原文地址:https://www.cnblogs.com/lixiang1993/p/7449943.html
Copyright © 2011-2022 走看看