### 1.Advice接口
![image](https://note.youdao.com/yws/public/resource/97367b3fa79f9c35015806db95fdb356/xmlnote/WEBRESOURCEfe38381cd2c6ebdc59c989d230169b17/3511)
上圖為AOP中通知(Advice)接口的實現與繼承關系。
最常用的兩個 BeforeAdvice 與AfterAdvice,AfterAdvice又被AfterReturnAdvice與ThrowsAdvice接口繼承
###? 2.BeforeAdvice的實現方式
1.實現了BeforeAdvice接口要重寫B(tài)efore方法
```
/**
? * method為被代理的方法涕癣,就是要在這個方法前面執(zhí)行一些操作
? * args 為參數列表
? * target 為被代理的類的一個對象
**/
public void before(Method method, Object[] args, Object target) throws Throwable {
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
```
2.以AspectJMethodBeforeAdvice類為例
before方法調用了AbstractAspectJAdvice類中的invokeAdviceMethod(getJoinPointMatch(), null, null);
```
/**
* 調用
* @param 獲取連接點信息
* @param 返回類型
* @param 異常
* @return the invocation result
* @throws Throwable in case of invocation failure
*/
protected Object invokeAdviceMethod(JoinPointMatch jpMatch, Object returnValue, Throwable ex) throws Throwable {
return invokeAdviceMethodWithGivenArgs(argBinding(getJoinPoint(), jpMatch, returnValue, ex));
}
```
其中第一參數連接點JoinPoint接口集乔,就是用來將代理對象與目標對象進行連接的一個接口
AspectJ中的切入點匹配的執(zhí)行點稱作連接的(JoinPoint)基公,
在通知方法中可以聲明一個JoinPoint類型的參數空盼。通過JoinPoint可以訪問連接點的細節(jié)浑劳。
下面簡要介紹JponPoint的方法:
==連接點是在什么時候生成的????==
```
1.java.lang.Object[] getArgs():獲取連接點方法運行時的入參列表蚕愤;?
2.Signature getSignature() :獲取連接點的方法簽名對象晦溪;?
3.java.lang.Object getTarget() :獲取連接點所在的目標對象瀑粥;?
4.java.lang.Object getThis() :獲取代理對象本身;?
```
ProceedingJoinPoint繼承JoinPoint子接口三圆,它新增了兩個用于執(zhí)行連接點方法的方法:?
```
5.java.lang.Object proceed() throws java.lang.Throwable:通過反射執(zhí)行目標對象的連接點處的方法狞换;?
6.java.lang.Object proceed(java.lang.Object[] args) throws java.lang.Throwable:通過反射執(zhí)行目標對象連接點處的方法,不過使用新的參數替換原來的參數舟肉。
```
3.執(zhí)行相關的函數
```
protected Object invokeAdviceMethod(JoinPointMatch jpMatch, Object returnValue, Throwable ex) throws Throwable {
return invokeAdviceMethodWithGivenArgs(argBinding(getJoinPoint(), jpMatch, returnValue, ex));
}
```
其中argBinding(getJoinPoint(), jpMatch, returnValue, ex)
```
/**
* Take the arguments at the method execution join point and output a set of arguments
* to the advice method
* @param jp the current JoinPoint
* @param jpMatch the join point match that matched this execution join point
* @param returnValue the return value from the method execution (may be null)
* @param ex the exception thrown by the method execution (may be null)
* @return the empty array if there are no arguments
*/
protected Object[] argBinding(JoinPoint jp, JoinPointMatch jpMatch, Object returnValue, Throwable ex) {
calculateArgumentBindings();
// AMC start
Object[] adviceInvocationArgs = new Object[this.adviceInvocationArgumentCount];
int numBound = 0;
if (this.joinPointArgumentIndex != -1) {
adviceInvocationArgs[this.joinPointArgumentIndex] = jp;
numBound++;
}
else if (this.joinPointStaticPartArgumentIndex != -1) {
adviceInvocationArgs[this.joinPointStaticPartArgumentIndex] = jp.getStaticPart();
numBound++;
}
if (!CollectionUtils.isEmpty(this.argumentBindings)) {
// binding from pointcut match
if (jpMatch != null) {
PointcutParameter[] parameterBindings = jpMatch.getParameterBindings();
for (PointcutParameter parameter : parameterBindings) {
String name = parameter.getName();
Integer index = this.argumentBindings.get(name);
adviceInvocationArgs[index] = parameter.getBinding();
numBound++;
}
}
// binding from returning clause
if (this.returningName != null) {
Integer index = this.argumentBindings.get(this.returningName);
adviceInvocationArgs[index] = returnValue;
numBound++;
}
// binding from thrown exception
if (this.throwingName != null) {
Integer index = this.argumentBindings.get(this.throwingName);
adviceInvocationArgs[index] = ex;
numBound++;
}
}
if (numBound != this.adviceInvocationArgumentCount) {
throw new IllegalStateException("Required to bind " + this.adviceInvocationArgumentCount
+ " arguments, but only bound " + numBound + " (JoinPointMatch " +
(jpMatch == null ? "was NOT" : "WAS") +
" bound in invocation)");
}
```
最后執(zhí)行
```
protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
Object[] actualArgs = args;
if (this.aspectJAdviceMethod.getParameterTypes().length == 0) {
actualArgs = null;
}
try {
ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);
// TODO AopUtils.invokeJoinpointUsingReflection
return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);
}
catch (IllegalArgumentException ex) {
throw new AopInvocationException("Mismatch on arguments to advice method [" +
this.aspectJAdviceMethod + "]; pointcut expression [" +
this.pointcut.getPointcutExpression() + "]", ex);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
```