Spring----面向切面編程和通知類型

面向過程:算法+數據結構java

面向對象(OOP):對象+消息算法

面向接口:多態性spring

面向切面(AOP):把非業務邏輯的功能,提取出來,定義成一個一個的切面。當你的程序運行到這個切面後,自動完成這個切面的全部功能。apache

 

AOP簡介

 前置通知數據結構

 切入點表達式app

//在applicationContext.xml文件中配置-----掃描帶註解的包----表示使用動態代理測試

 編寫一個切面類

 裏面的註解@Before上的value值是切入點(哪一個類下的哪一個方法)spa

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=黑色]]

 後置通知

 

切點表達式解釋

返回通知

異常通知3d

環繞通知

 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文件。代理

相關文章
相關標籤/搜索