1. 程式人生 > >spring AOP切面程式設計——基於自定義註解

spring AOP切面程式設計——基於自定義註解

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