• Spring----面向切面编程和通知类型


    面向过程:算法+数据结构

    面向对象(OOP):对象+消息

    面向接口:多态性

    面向切面(AOP):把非业务逻辑的功能,提取出来,定义成一个一个的切面。当你的程序运行到这个切面后,自动完成这个切面的所有功能。

    AOP简介

     前置通知

     切入点表达式

    //在applicationContext.xml文件中配置-----扫描带注解的包----表示使用动态代理

     编写一个切面类

     里面的注解@Before上的value值是切入点(哪个类下的哪个方法)

    package com.aspect;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.springframework.stereotype.Component;
    
    //定义了日志切面 
    @Aspect//表示这个类是一个切面
    @Component//把普通法的pojo实例化到Spring容器中,相当于配置文件中的<bean id="" class=""/>
    public class LoggingAspect {
        
        //前置通知===参数:切入点表达式--指定类的所有方法--括号里面是参数
        //切入点为--该指定类且参数为Students的方法---也就是add方法
        @Before("execution(public * com.dao.impl.StudentsDAOImpl.* (com.entity.Students))")
        public void before(JoinPoint point){
            System.out.println("before:"+point.getSignature().getName()+"("+point.getArgs()+")");
        }
    }

    在applicationContext.xml配置文件中添加相关标签

        <!-- 表示使用注解 -->
        <context:annotation-config/>
        
        <!-- 表示使用动态代理 -->
        <aop:aspectj-autoproxy proxy-target-class="true"/>
        
        <!-- 扫描带注解的包 -->
        <context:component-scan base-package="com"/>

    测试结果:----会在指定的dao层add方法之前切入这个方法执行

    一辆汽车诞生啦...
    一个学生创建啦...
    执行了setName()方法
    service层保存学生Students [sid=s0006, name=IU, gender=女, birthday=Wed Jul 15 00:00:00 GMT+08:00 1998, address=韩国首尔, car=Car [brand=BMW, color=黑色]]
    before:add([Ljava.lang.Object;@11cbbeb1)
    dao层保存学生Students [sid=s0006, name=IU, gender=女, birthday=Wed Jul 15 00:00:00 GMT+08:00 1998, address=韩国首尔, car=Car [brand=BMW, color=黑色]]

     后置通知

     

    切点表达式解释

    返回通知

    异常通知

    环绕通知

     AOP相关术语

    使用日志log4j. properties

    log4j.rootLogger=INFO,stdout,R
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    #Pattern to output the caller's file name and line number.
    #log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
    #Print the date in ISO 8601 format
    log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
    log4j.appender.R=org.apache.log4j.RollingFileAppender
    log4j.appender.R.File=example.log
    log4j.appender.R.MaxFileSize=100KB
    # Keep one backup file
    log4j.appender.R.MaxBackupIndex=1
    log4j.appender.R.layout=org.apache.log4j.PatternLayout
    log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n
    # Print only messages of level WARN or above in the package com.foo.
    # log4j.logger.com.foo=WARN

    定义的日志切面(类)

    package com.aspect;
    
    import org.apache.log4j.LogManager;
    import org.apache.log4j.Logger;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.AfterThrowing;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.springframework.stereotype.Component;
    
    //定义了日志切面 
    @Aspect//表示这个类是一个切面
    @Component//把普通法的pojo实例化到Spring容器中,相当于配置文件中的<bean id="" class=""/>
    public class LoggingAspect {
        
        //创建一个日志对象
        private static Logger logger=LogManager.getLogger(LoggingAspect.class.getName());
        
        
        //前置通知===参数:切入点表达式--指定类的所有方法--括号里面是参数
        //切入点为--该指定类且参数为Students的方法---也就是add方法
        @Before("execution(public * com.dao.impl.StudentsDAOImpl.* (com.entity.Students))")
        public void before(JoinPoint point){
    //        System.out.println("before:"+point.getSignature().getName()+"("+point.getArgs()+")");
            System.out.println("前置日志信息:"+point.getSignature().getName()+"");
            logger.info("前置日志信息:"+point.getSignature().getName()+"");
        }
        
        
        //后置通知
        @After("execution(public * com.dao.impl.StudentsDAOImpl.* (com.entity.Students))")
        public void after(JoinPoint point){
            System.out.println("后置日志信息:"+point.getSignature().getName()+"");
            logger.info("后置日志信息:"+point.getSignature().getName()+"");
        }
        
        
        //返回通知
        @AfterReturning(value="execution(public * com.dao.impl.StudentsDAOImpl.* (com.entity.Students))",returning="result")
        public void afterReturning(JoinPoint point,Object result){
            System.out.println("返回通知:"+point.getSignature().getName()+"("+point.getArgs()+")"+",result:"+result);
            logger.info("返回通知:"+point.getSignature().getName()+"("+point.getArgs()+")"+",result:"+result);
        }
        
        //异常通知
        @AfterThrowing(value="execution(public * com.dao.impl.StudentsDAOImpl.* (com.entity.Students))",throwing="ex")
        public void afterThrowing(JoinPoint point,Exception ex){
            System.out.println("异常通知:"+point.getSignature().getName()+"("+point.getArgs()+")"+",exception:"+ex);
            logger.info("异常通知:"+point.getSignature().getName()+"("+point.getArgs()+")"+",exception:"+ex);
        }
        
        //环绕通知
        @Around("execution(public * com.dao.impl.StudentsDAOImpl.* (com.entity.Students))")
        public Object around(ProceedingJoinPoint point) throws Throwable{
            Object result=null;
            System.out.println("环绕通知之前要做的事情:"+point.getSignature().getName());
                //在这个地方是有throws Throwable,以便在异常通知时,获取异常信息
                result=point.proceed();
            
            System.out.println("环绕通知之后要做的事情:"+point.getSignature().getName());
            return result;
        }
        
        
    }

    applicationContext.xml文件:

        <!-- 表示使用注解 -->
        <context:annotation-config/>
        
        <!-- 表示使用动态代理 -->
        <aop:aspectj-autoproxy proxy-target-class="true"/>
        
        <!-- 扫描带注解的包 -->
        <context:component-scan base-package="com"/>

    测试然后会在控制台打印出日志,以及生成日志文件example.log文件。

  • 相关阅读:
    Hbase与Maven工程的Spring配置笔记
    CentOS7.0+Hadoop2.7.2+Hbase1.2.1搭建教程
    利用Python进行博客图片压缩
    Qt下Armadillo矩阵函数库的添加
    Qt下Eigen矩阵函数库的添加
    OpenCV2.4.13+VS2013配置方法
    OpenCV2.4.13+Qt5.6.2配置方法
    异想家Win10系统安装的软件与配置
    异想家Win7系统安装的软件与配置
    STM32学习笔记:基础例子
  • 原文地址:https://www.cnblogs.com/xjs1874704478/p/11214299.html
Copyright © 2020-2023  润新知