spring AOP切面程式設計——基於自定義註解
阿新 • • 發佈:2019-01-05
AOP稱為面向切面程式設計,在程式開發中主要用來解決一些系統層面上的問題,比如日誌,事務,許可權等待,
(1)Aspect(切面):通常是一個類,裡面可以定義切入點和通知 (2)JointPoint(連線點):程式執行過程中明確的點,一般是方法的呼叫 (3)Advice(通知):AOP在特定的切入點上執行的增強處理,有before,after,afterReturning,afterThrowing,around (4)Pointcut(切入點):就是帶有通知的連線點,在程式中主要體現為書寫切入點表示式 (5)AOP代理:AOP框架建立的物件,代理就是目標物件的加強。Spring中的AOP代理可以使JDK動態代理,也可以是CGLIB代理,前者基於介面,後者基於子類
需要jar包 spring-aspects-3.2.0.RELEASE.jar、spring-aop-3.2.0.RELEASE.jar
//切入控制層
@SysLog("修改密碼")
自定義註解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLog {
String value() default "";
}
切面程式設計的實際使用
@Aspect @Component public class SysLogAspect { @Autowired private SysLogService sysLogService; 1、執行到這 @Pointcut("@annotation(io.renren.common.annotation.SysLog)") public void logPointCut() { } @Around("logPointCut()") public Object around(ProceedingJoinPoint point) throws Throwable { long beginTime = System.currentTimeMillis(); //執行方法 2、執行到contorl Object result = point.proceed(); //執行時長(毫秒) long time = System.currentTimeMillis() - beginTime; 3、執行完contorl後執行此處 //儲存日誌 saveSysLog(point, time); return result; } private void saveSysLog(ProceedingJoinPoint joinPoint, long time) { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); 4、ProceedingJoinPoint joinPoint \\MethodSignature signature \\Method method \\joinPoint.getTarget().getClass().getName() SysLogEntity sysLog = new SysLogEntity(); SysLog syslog = method.getAnnotation(SysLog.class); if(syslog != null){ //註解上的描述 sysLog.setOperation(syslog.value()); } //請求的方法名 String className = joinPoint.getTarget().getClass().getName(); String methodName = signature.getName(); sysLog.setMethod(className + "." + methodName + "()"); //請求的引數 Object[] args = joinPoint.getArgs(); try{ String params = new Gson().toJson(args[0]); sysLog.setParams(params); }catch (Exception e){ } //獲取request HttpServletRequest request = HttpContextUtils.getHttpServletRequest(); //設定IP地址 sysLog.setIp(IPUtils.getIpAddr(request)); //使用者名稱 String username = ((SysUserEntity) SecurityUtils.getSubject().getPrincipal()).getUsername(); sysLog.setUsername(username); sysLog.setTime(time); sysLog.setCreateDate(new Date()); //儲存系統日誌 sysLogService.insert(sysLog); } }
底層原始碼__動態代理呼叫、
public Object proceed() throws Throwable {
return this.methodInvocation.invocableClone().proceed();
}
spring AOP底層原理 詳見 https://blog.csdn.net/eson_15/article/details/84933442