前言
1,在一些特定的場景我們往往需要看一下介面的入參,特別是跨系統的介面呼叫(下發,推送),這個時候的介面入參就很重要,我們保存入參入庫,如果出問題就可以馬上定位是上游還是下游的問題(方便扯皮)
2,還有一般需要在系統中看普通日志,還有特殊的例外(報錯)日志,一般我們可以通過服務器去查看相應的位置,但是由于服務器是一直運行的,日志是一直在生成的,這個時候就不太方便,
3,保存入參,我們之間本地除錯的時候就可以不用造資料,這個也是很方便的,只需改改就好,
這個時候就體現入參請求和相應結果的重要性
Aop基本概念
Aspect(切面): Aspect 宣告類似于 Java 中的類宣告,在 Aspect 中會包含著一些 Pointcut 以及相應的 Advice,
Joint point(連接點):表示在程式中明確定義的點,典型的包括方法呼叫,對類成員的訪問以及例外處理程式塊的執行等等,它自身還可以嵌套其它 joint point,
Pointcut(切點):表示一組 joint point,這些 joint point 或是通過邏輯關系組合起來,或是通過通配、正則運算式等方式集中起來,它定義了相應的 Advice 將要發生的地方,
Advice(增強):Advice 定義了在 Pointcut 里面定義的程式點具體要做的操作,它通過 before、after 和 around 來區別是在每個 joint point 之前、之后還是代替執行的代碼,
Target(目標物件):織入 Advice 的目標物件.,
Weaving(織入):將 Aspect 和其他物件連接起來, 并創建 Adviced object 的程序
自定義注解:
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface UserAccess {
String desc() default "無資訊";
}
對自定義注解進行aop切面
一般使用更加詳細的日志切面
@Component
@Aspect
public class UserAccessAspect {
// 這里就是對上面進行切面
@Pointcut(value = "https://www.cnblogs.com/blbl-blog/p/@annotation(com.xncoding.aop.aspect.UserAccess)")
public void access() {
}
@Before("access()")
public void deBefore(JoinPoint joinPoint) throws Throwable {
System.out.println("second before");
}
@Around("@annotation(userAccess)")
public Object around(ProceedingJoinPoint pjp, UserAccess userAccess) {
//獲取注解里的值
System.out.println("second around:" + userAccess.desc());
try {
return pjp.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
return null;
}
}
}
日志切面
如果想保存到資料庫或者進行更加詳細的日志列印就可以使用下面的日志切面,
這里目前是列印,如果想保存到資料庫,可以創建相應的物體,set進去,然后進行insert到資料庫,如果使用mybatis-plus是很方便的,先創建表,然后用mybatis-plus 自動生成代碼,再用相應的mapper.inster() 保存到資料庫,
/**
* 日志切面
*/
@Aspect
@Component
public class LogAspect {
// 這個目前是對從 com.xncoding.aop.controller.* 下的都進行切入,如果想對上面的自定義注解進行切入,只需改成相對應的路徑
// 例如:@Pointcut(value = "https://www.cnblogs.com/blbl-blog/p/@annotation(com.xncoding.aop.aspect.UserAccess)")
@Pointcut("execution(public * com.xncoding.aop.controller.*.*(..))")
public void webLog(){}
@Before("webLog()")
public void deBefore(JoinPoint joinPoint) throws Throwable {
// 接收到請求,記錄請求內容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// 記錄下請求內容
System.out.println("URL : " + request.getRequestURL().toString());
System.out.println("HTTP_METHOD : " + request.getMethod());
System.out.println("IP : " + request.getRemoteAddr());
System.out.println("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
System.out.println("ARGS : " + Arrays.toString(joinPoint.getArgs()));
}
@AfterReturning(returning = "ret", pointcut = "webLog()")
public void doAfterReturning(Object ret) throws Throwable {
// 處理完請求,回傳內容
System.out.println("方法的回傳值 : " + ret);
}
//后置例外通知
@AfterThrowing("webLog()")
public void throwss(JoinPoint jp){
System.out.println("方法例外時執行.....");
}
//后置最終通知,final增強,不管是拋出例外或者正常退出都會執行
@After("webLog()")
public void after(JoinPoint jp){
System.out.println("方法最后執行.....");
}
//環繞通知,環繞增強,相當于MethodInterceptor
@Around("webLog()")
public Object arround(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("方法環繞start.....");
try {
Object o = pjp.proceed();
System.out.println("方法環繞proceed,結果是 :" + o);
return o;
} catch (Throwable e) {
throw e;
}
}
}
測驗controller
@RestController
@RequestMapping("aop")
public class UserController {
@GetMapping("/first")
public Object first() {
return "first controller";
}
@GetMapping("/doError")
public Object error() {
return 1 / 0;
}
@GetMapping("/second")
@UserAccess(desc = "second")
public Object second() {
return "second controller 666";
}
@PostMapping("/user")
public void userPost(@RequestBody UserVo userVo){
System.out.println("我user進來了");
}
}
user類
@Data
public class UserVo {
@ApiModelProperty("姓名")
private String name;
@ApiModelProperty("性別")
private Integer sex;
}
創建表SQL陳述句
CREATE TABLE `sys_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`log_type` varchar(50) NOT NULL COMMENT '日志型別',
`create_user_code` varchar(64) NOT NULL COMMENT '創建用戶編碼',
`create_user_name` varchar(100) NOT NULL COMMENT '創建用戶名稱',
`create_date` datetime NOT NULL COMMENT '創建時間',
`request_uri` varchar(500) DEFAULT NULL COMMENT '請求URI',
`request_method` varchar(10) DEFAULT NULL COMMENT '請求方式',
`request_params` text COMMENT '請求引數',
`response_params` text COMMENT '回應引數',
`request_ip` varchar(20) NOT NULL COMMENT '請求IP',
`server_address` varchar(50) NOT NULL COMMENT '請求服務器地址',
`is_exception` char(1) DEFAULT NULL COMMENT '是否例外',
`exception_info` text COMMENT '例外資訊',
`start_time` datetime NOT NULL COMMENT '開始時間',
`end_time` datetime NOT NULL COMMENT '結束時間',
`execute_time` int(11) DEFAULT NULL COMMENT '執行時間',
`user_agent` varchar(500) DEFAULT NULL COMMENT '用戶代理',
`device_name` varchar(100) DEFAULT NULL COMMENT '作業系統',
`browser_name` varchar(100) DEFAULT NULL COMMENT '瀏覽器名稱',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_sys_log_lt` (`log_type`) USING BTREE,
KEY `idx_sys_log_cub` (`create_user_code`) USING BTREE,
KEY `idx_sys_log_ie` (`is_exception`) USING BTREE,
KEY `idx_sys_log_cd` (`create_date`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1560559854462500867 DEFAULT CHARSET=utf8 COMMENT='系統日志表';
測驗
請求引數:

debug圖片

這里只是做列印,也可以在切面里面保存到資料庫,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/502696.html
標籤:Java
下一篇:Java列舉簡單介紹
