您好,登錄后才能下訂單哦!
本文源碼: GitHub·點(diǎn)這里 || GitEE·點(diǎn)這里
在軟件業(yè),AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程,通過預(yù)編譯方式和運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)。AOP是OOP(面向?qū)ο缶幊蹋┑难永m(xù),是軟件開發(fā)中的一個(gè)熱點(diǎn),也是Spring框架中的一個(gè)重要內(nèi)容,是函數(shù)式編程的一種衍生范型。利用AOP可以對(duì)業(yè)務(wù)邏輯的各個(gè)部分進(jìn)行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時(shí)提高了開發(fā)的效率。
1)AOP采取橫向抽取機(jī)制,取代了傳統(tǒng)縱向繼承體系重復(fù)性代碼
2)經(jīng)典應(yīng)用:事務(wù)管理、性能監(jiān)視、安全檢查、緩存 、日志等
3)aop底層將采用代理機(jī)制進(jìn)行實(shí)現(xiàn)
4)接口 + 實(shí)現(xiàn)類 :spring采用 jdk 的動(dòng)態(tài)代理Proxy
5)實(shí)現(xiàn)類:spring 采用 cglib字節(jié)碼增強(qiáng)
1)target:目標(biāo)類
需要被代理的類。例如:UserService
2)Joinpoint:連接點(diǎn)
所謂連接點(diǎn)是指那些可能被攔截到的方法。例如:所有的方法
3)PointCut:切入點(diǎn)
已經(jīng)被增強(qiáng)的連接點(diǎn)。例如:addUser()
4)advice:通知/增強(qiáng)
增強(qiáng)代碼。例如:after、before
5)Weaving:織入
指把增強(qiáng)advice應(yīng)用到目標(biāo)對(duì)象target來創(chuàng)建新的代理對(duì)象proxy的過程.
6)proxy 代理類
7) Aspect(切面): 是切入點(diǎn)pointcut和通知advice的結(jié)合
一個(gè)線是一個(gè)特殊的面。
一個(gè)切入點(diǎn)和一個(gè)通知,組成成一個(gè)特殊的面。
<!-- AOP依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
package com.boot.aop.config;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogFilter {
String value() default "" ;
}
這里分為兩種情況處理,一種正常的請(qǐng)求日志,和系統(tǒng)異常的錯(cuò)誤日志。
核心注解兩個(gè)。
@Aspect和
@Component。
package com.boot.aop.config;
import com.alibaba.fastjson.JSONObject;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
@Aspect
@Component
public class LogAspect {
private static final Logger LOGGER = LoggerFactory.getLogger(LogAspect.class) ;
@Pointcut("@annotation(com.boot.aop.config.LogFilter)")
public void logPointCut (){
}
@Around("logPointCut()")
public Object around (ProceedingJoinPoint point) throws Throwable {
Object result = null ;
try{
// 執(zhí)行方法
result = point.proceed();
// 保存請(qǐng)求日志
saveRequestLog(point);
} catch (Exception e){
// 保存異常日志
saveExceptionLog(point,e.getMessage());
}
return result;
}
private void saveExceptionLog (ProceedingJoinPoint point,String exeMsg){
LOGGER.info("捕獲異常:"+exeMsg);
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
LOGGER.info("請(qǐng)求路徑:"+request.getRequestURL());
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
LOGGER.info("請(qǐng)求方法:"+method.getName());
// 獲取方法上LogFilter注解
LogFilter logFilter = method.getAnnotation(LogFilter.class);
String value = logFilter.value() ;
LOGGER.info("模塊描述:"+value);
Object[] args = point.getArgs();
LOGGER.info("請(qǐng)求參數(shù):"+ JSONObject.toJSONString(args));
}
private void saveRequestLog (ProceedingJoinPoint point){
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
LOGGER.info("請(qǐng)求路徑:"+request.getRequestURL());
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
LOGGER.info("請(qǐng)求方法:"+method.getName());
// 獲取方法上LogFilter注解
LogFilter logFilter = method.getAnnotation(LogFilter.class);
String value = logFilter.value() ;
LOGGER.info("模塊描述:"+value);
Object[] args = point.getArgs();
LOGGER.info("請(qǐng)求參數(shù):"+ JSONObject.toJSONString(args));
}
}
@LogFilter("保存請(qǐng)求日志")
@RequestMapping("/saveRequestLog")
public String saveRequestLog (@RequestParam("name") String name){
return "success:"+name ;
}
切面類信息打印
/**
* 請(qǐng)求路徑:http://localhost:8011/saveRequestLog
* 請(qǐng)求方法:saveRequestLog
* 模塊描述:保存請(qǐng)求日志
* 請(qǐng)求參數(shù):["cicada"]
*/
@LogFilter("保存異常日志")
@RequestMapping("/saveExceptionLog")
public String saveExceptionLog (@RequestParam("name") String name){
int error = 100 / 0 ;
System.out.println(error);
return "success:"+name ;
}
切面類信息打印
/**
* 捕獲異常:/ by zero
* 請(qǐng)求路徑:http://localhost:8011/saveExceptionLog
* 請(qǐng)求方法:saveExceptionLog
* 模塊描述:保存異常日志
* 請(qǐng)求參數(shù):["cicada"]
*/
GitHub·地址
https://github.com/cicadasmile/spring-boot-base
GitEE·地址
https://gitee.com/cicadasmile/spring-boot-base
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。