Advice
advice解释为通知,需要执行的增强逻辑方法。
advice规范接口如图,分为了before,after等等,为什么没有around呢,因为是通过interceptor实现的。

这里可以看出,AfterAdvice最终会被转换包装成AfterReturningAdviceInterceptor实现类进行适配桥接,同理BeforeAdvice也会被包装成MethodBeforeAdviceInterceptor最终调用MethodIntercepter#invoke()方法进行适配。
限于图片展示范围以上均是还没有到具体API使用实现类,我们继续探究其实现类

PointCut
pointCut解释为切点,即我们需要给哪些方法进行代理增强,也就是切面定义中的切点表达式,根据这个表达式能匹配到具体需要增强的方法,根据该接口的规范我们可以看到其实现类持有了切点表达式pointcoutExpression,匹配的方法shadowMatchCache缓存。

其接口定义的方法规范:

Advisor
advisor解释为通知者,他是Advice和PointCut的结合,组合了通知和切点那么就能很明确的知道那个方法需要增强什么逻辑,在Advisor中Advice和PointCut是一对一的。

可以看到针对不同类型的切点表达式有具体实现,其侧重点不一样,其中DefaultPointcutAdvisor是全匹配,即匹配所有类的所有方法(默认情况,可以改变表达式)。
而接口方法为:

从接口方法很容易看到Advisor就是Advice和Pointcut的组合,从中可以获取Advice和Pointcut。
Advised
advised可以理解为已经织如的,完成的代理组合体,Advised接口定义了很多操作方法,其实现类持有了多个Advisor,可以向Advised对象中添加Advisor,同时可对Advisor进行增删查改(isFrozen=false时)。

在spring中默认情况下ProxyConfig的opaque=false情况下,生成的所有代理对象无论是JDK代理还是CJLIB代理均实现了Advised接口,也就是说在Spring中我们可以将所有的代理对象转为AdvisedAdvised advised = (Advised)proxy。
有一段代码如下:
public static void main(String[] args) {DefaultEchoService defaultEchoService = new DefaultEchoService();// 注入目标对象(被代理)ProxyFactory proxyFactory = new ProxyFactory(defaultEchoService);// 添加 Advice 实现 MethodInterceptor < Interceptor < AdviceproxyFactory.addAdvice(new EchoServiceMethodInterceptor());// 获取代理对象EchoService proxy = (EchoService) proxyFactory.getProxy();System.out.println(proxy.echo("Hello,World"));Advised advised = (Advised) proxy;//直接给代理对象添加通知(会被包装为匹配所有方法的Advisor)advised.addAdvice(new MethodBeforeAdvice() {@Overridepublic void before(Method method, Object[] args, Object target) throws Throwable {System.out.println("before--------------");}});System.out.println(proxy.echo("hello 2"));//代理对象还可以二次代理ProxyFactory pf1 = new ProxyFactory(proxy);Object proxy2 = pf1.getProxy();System.out.println(proxy2.getClass());
}
我们debug看下代理对象信息:

不难看出JdkDynamicAopProxy持有了一个Advised的实现类ProxyFactory,代理对象调用addAdvice()方法为什么可行,就是因为实际调用的是h对象的advised属性的addAdvice()去执行,将Advice添加到了Advised的Advisor集合中(advisors属性),这里就相当于静态代理模式。
在Spring中每个代理对象都有不同的JDKDynamicAopProxy实例(h对象都是new的),h对象中不同的ProxyFactory对象(advised实现)。这也不难理解,因为每个代理对象的增强逻辑不尽相同,那么其advisors集合中的通知者肯定不同,也就意味着ProxyFactory对象必定不同,也即InvocationHandler对象必定不同。
JdkDynamicAopProxy实现了InvocationHandler接口那么其实现的invoke()方法至关重要,后面我们接着分析。
到这里我们似乎已经很好理解Advised的本意了,他就是已经织如完成的通知者集合,包含在代理对象中,代理对象已经可以直接使用,在被增强的方法上会调用通知方法。
JoinPoint
joinpoint就是运行时的连接点,根据接口定义我们知道它包裹了要执行的对象,方法,参数等。spring只支持方法类型的连接点,虽然有构造方法连接点的定义,但是未实现,故不支持构造方法。

我们可以看到这里有两种实现方式,意识基于jdk的动态代理,二是基于cglib实现。
各个接口定义的方法:

joinpoint就是运行时的连接点,根据接口定义我们知道它包裹了要执行的对象,方法,参数等。spring只支持方法类型的连接点,虽然有构造方法连接点的定义,但是未实现,故不支持构造方法。

我们可以看到这里有两种实现方式,意识基于jdk的动态代理,二是基于cglib实现。 各个接口定义的方法: 在jdk代理模式时,Jointpoint的使用是在InvocationHandler的实现类JdkDynamicAopProxy中的invoke()方法中被创建(new),我们再看invoke方法:
Jointpoint使用
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object oldProxy = null;boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;Object target = null;
try {// 省略部分代码...Object retVal;
// 暴露代理对象,在执行方法中可以通过ThreadLocal获得if (this.advised.exposeProxy) {// Make invocation available if necessary.oldProxy = AopContext.setCurrentProxy(proxy);setProxyContext = true;}
// Get as late as possible to minimize the time we "own" the target,// in case it comes from a pool.target = targetSource.getTarget();Class<?> targetClass = (target != null ? target.getClass() : null);
// 获得通知执行链List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);if (chain.isEmpty()) {Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);} else {//创建连接点实现类,包装了代理对象,目标类,要执行的方法,参数,目标类,拦截器链等等MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);//可以看到MethodInvocation的proceed()至关重要retVal = invocation.proceed();}
// Massage return value if necessary.Class<?> returnType = method.getReturnType();if (retVal != null && retVal == target &&returnType != Object.class && returnType.isInstance(proxy) &&!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {// Special case: it returned "this" and the return type of the method// is type-compatible. Note that we can't help if the target sets// a reference to itself in another returned object.retVal = proxy;}else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {throw new AopInvocationException("Null return value from advice does not match primitive return type for: " + method);}return retVal;}finally {if (target != null && !targetSource.isStatic()) {// Must have come from TargetSource.targetSource.releaseTarget(target);}//修改代理对象为上一个,类似于线程池的ThreadLocal设计if (setProxyContext) {// Restore old proxy.AopContext.setCurrentProxy(oldProxy);}}
}
JoinPoint
在JoinPoint中定义了多个方法
public interface Joinpoint {// 继续执行拦截器链@NullableObject proceed() throws Throwable;// 获取当前对象@NullableObject getThis();// @NonnullAccessibleObject getStaticPart();
}
MethodInvocation在此基础上增加了method方法的获取,这个方法就是要执行的原始方法,增强逻辑中最后调用。
MethodInvocation
public interface MethodInvocation extends Invocation {@NonnullMethod getMethod();
}
继续扩展了代理信息获取规范接口:
ProxyMethodInvocation
public interface ProxyMethodInvocation extends MethodInvocation {// 返回原始对象的代理对象Object getProxy();
MethodInvocation invocableClone();MethodInvocation invocableClone(Object... arguments);// 调用方法的参数设置,但是实现类一般通过构造方法设置void setArguments(Object... arguments);
// 其他属性设置void setUserAttribute(String key, @Nullable Object value);@NullableObject getUserAttribute(String key);
}
实现类ReflectiveMethodInvocation
public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {// 代理后的代理对象protected final Object proxy;// 原始对象@Nullableprotected final Object target;// 方法protected final Method method;// 方法参数protected Object[] arguments;// 原始类Class@Nullableprivate final Class<?> targetClass;// 相关属性保存集合@Nullableprivate Map<String, Object> userAttributes;// 查找到的拦截器也就是Advisorsprotected final List<?> interceptorsAndDynamicMethodMatchers;// 运行时执行到哪个拦截器了private int currentInterceptorIndex = -1;// 构造方法protected ReflectiveMethodInvocation(Object proxy, @Nullable Object target, Method method, @Nullable Object[] arguments,@Nullable Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {
this.proxy = proxy;this.target = target;this.targetClass = targetClass;this.method = BridgeMethodResolver.findBridgedMethod(method);this.arguments = AopProxyUtils.adaptArgumentsIfNecessary(method, arguments);this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;}
}
ReflectiveMethodInvocation是Jointpoint最核心实现,从代码上看也是非常的简单,它在代理对象执行方法时被创建。
















