首先我们需要知道的是,调用这个方法的是 createAopProxy() 方法的返回值,那么就可能是JdkDynamicAopProxy.getProxy 或者 ObjenesisCglibAopProxy.getProxy。下面我们来详细分析一下代理生成的过程。
下面代码省略了JdkDynamicAopProxy 部分无关代码。
对于JDK 动态代理来说,实际调用代理方法是在 java.lang.reflect.InvocationHandler#invoke 中,因此 JdkDynamicAopProxy#invoke是我们的重点关注对象。
@Override
public Object getProxy() {
return getProxy(ClassUtils.getDefaultClassLoader());
}
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
}@Override
@Nullable
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 {
// 处理 equals 方法
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
// 处理 hashCode 方法
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
}
// 处理 DecoratingProxy 类
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
return AopProxyUtils.ultimateTargetClass(this.advised);
}
// 处理 Class类的isAssignableFrom(Class cls) 方法
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
// 是否暴露代理对象。有时候目标对象内部的自我调用将无法实施切面中的增强,则需要通过此属性暴露
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);
// Get the interception chain for this method.
// 获取当前方法的拦截链路,其中包括将AspectJMethodBeforeAdvice、AspectJAfterAdvice、AspectJAfterReturningAdvice 转换成合适的类型(InterceptorAndDynamicMethodMatcher)
List上面我们有两个方法需要注意:
我们讲了在 InstantiationModelAwarePointcutAdvisorImpl 中,Spring根据Aspect系列注解的不同将方法封装成了不同的Advice :AspectJAroundAdvice、AspectJMethodBeforeAdvice、AspectJAfterAdvice、AspectJAfterReturningAdvice、AspectJAfterThrowingAdvice。
在 invocation.proceed() 的分析中我们会发现最终调用的增强方法为 MethodInterceptor#invoke方法。但是在上述五个Advice 中,只有AspectJAroundAdvice 和 AspectJAfterAdvice 实现了MethodInterceptor 接口,其余的并没有实现 MethodInterceptor 接口,那么这时候就需要进行一个转换,将 Advice 转换成 MethodInterceptor 类型,该转换就是在此方法中完成。
由于 this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); 方法最终会调用DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice,所以我们这里直接看该方法
public List我们可以看到关键的代码就是 registry.getInterceptors(advisor);,所以我们这里来看 DefaultAdvisorAdapterRegistry#getInterceptors 的 实现,其目的是将所有的Advisor中的Advice 转换成 MethodInterceptor。
@Override
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List interceptors = new ArrayList<>(3);
Advice advice = advisor.getAdvice();
// 如果 Advice 就是MethodInterceptor 类型,则直接保存
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
// 否则寻找合适的适配器进行转换。
// 这里的适配器有三个,分别是`AfterReturningAdviceAdapter`、`MethodBeforeAdviceAdapter`、`ThrowsAdviceAdapter`
for (AdvisorAdapter adapter : this.adapters) {
if (adapter.supportsAdvice(advice)) {
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[0]);
} 这里的适配器有三个,分别是AfterReturningAdviceAdapter、MethodBeforeAdviceAdapter、ThrowsAdviceAdapter。很明显就是为了上面的三个Advice类型准备的。经历过此步骤,所有的Advice 都转换为了 MethodInterceptor。我们这里挑选其中一个ThrowsAdviceAdapter 看:
class ThrowsAdviceAdapter implements AdvisorAdapter, Serializable {
@Override
public boolean supportsAdvice(Advice advice) {
return (advice instanceof ThrowsAdvice);
}
@Override
public MethodInterceptor getInterceptor(Advisor advisor) {
return new ThrowsAdviceInterceptor(advisor.getAdvice());
}
}逻辑很简答,就是将 ThrowsAdvice 封装成了ThrowsAdviceInterceptor。其他两个以此类推。
我们来看看 ReflectiveMethodInvocation#proceed 的实现,上面说过增强方法的调用实际上是在此完成的。
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
// 如果所有的增强器已经执行完了,则调用实际方法
// interceptorsAndDynamicMethodMatchers 是在2.2.1 中解析出来的动态拦截器集合
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
// 这里调用了真正的方法 通过Method.invoke 方法
return invokeJoinpoint();
}
// 获取下一个要调用的增强拦截器
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
// 动态匹配
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
// 如果当前增强匹配当前的方法,则调用增强
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
// 调用 拦截器的 invoke 方法
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
// 不匹配则不执行拦截器,递归调用,遍历下一个拦截器
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
// 普通的拦截器,直接调用拦截器。我们一般都走这里
// 将this 作为参数传递以保证当前实力中的调用链路的执行
// 直接调用 Advice 的 invoke 方法
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}在 ReflectiveMethodInvocation#process 方法中的逻辑并不复杂。ReflectiveMethodInvocation 中的主要职责是维护了链接调用的计数器,记录着当前调用链接的位置,以便链可以有序的进行下去,在这个方法中并没有维护各种增强的顺序,而是将此工作委托给了各个增强器,使各个增强器在内部进行逻辑实现。
在 JdkDynamicAopProxy#invoke 方法中:
class InterceptorAndDynamicMethodMatcher {
// MethodInterceptor 方法拦截器,这里保存了针对于该方法的增强实现
final MethodInterceptor interceptor;
// 方法匹配器,用来匹配当前拦截器是否适用于当前方法
final MethodMatcher methodMatcher;
public InterceptorAndDynamicMethodMatcher(MethodInterceptor interceptor, MethodMatcher methodMatcher) {
this.interceptor = interceptor;
this.methodMatcher = methodMatcher;
}
}至此,@Aspect 系列注解修饰的方法从 Advisor 转换成了 InterceptorAndDynamicMethodMatcher。
在调用invocation.proceed();方法时,针对 InterceptorAndDynamicMethodMatcher 类型,会通过InterceptorAndDynamicMethodMatcher#methodMatcher 判断是否适用于当前方法,如果适用则调用InterceptorAndDynamicMethodMatcher#interceptor 的 invoke 方法来执行增强方法。
我们来看一下 cglib 动态代理。
callback可以认为是cglib用于生成字节码的实现手段,cglib一共实现了6种callback,用于对代理类目标进行不同手段的代理,非常灵活,具体如下:
Spring Aop 的代理对象创建在 CglibAopProxy#getProxy(java.lang.ClassLoader) 中完成。其实现如下:
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
try {
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
// 如果当前类名中包含 “$” 则被认定为是 cglib 类。
if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
// 校验方法的合法性,但仅仅打印了日志
validateClassIfNecessary(proxySuperClass, classLoader);
// Configure CGLIB Enhancer...
// 配置 Enhancer
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
// 1. 获取代理的回调方法集合
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
// 2. 添加 Callback 过滤器。
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
// 创建代理对象
return createProxyClassAndInstance(enhancer, callbacks);
}
...
}这里我们知道 CglibAopProxy#getCallbacks 会返回一个Callback集合,而 Cglib 的代理对象是通过 ProxyCallbackFilter 中的策略来确定什么场景下使用不同的 Callback。
因此下面我们来看一下这两个类的具体实现:
CglibAopProxy#getCallbacks 是生成代理类的 Callback。具体实现如下:
// 上面可以很明显知道,CallBack是代理增强的关键实现。
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
// Parameters used for optimization choices...
// 是否暴露代理类
boolean exposeProxy = this.advised.isExposeProxy();
// 是否被冻结
boolean isFrozen = this.advised.isFrozen();
// 是否静态类,这里的静态并非指静态类,而是每次调用返回的实例都是否是不可变的
// 如单例模式的bean就是静态,而多例模式下的bean就不是静态
boolean isStatic = this.advised.getTargetSource().isStatic();
// Choose an "aop" interceptor (used for AOP calls).
// 创建 Aop 拦截器
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
// Choose a "straight to target" interceptor. (used for calls that are
// unadvised but can return this). May be required to expose the proxy.
Callback targetInterceptor;
// 根据是否包括和 静态,来生成不同的拦截器
if (exposeProxy) {
targetInterceptor = (isStatic ?
new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()));
}
else {
targetInterceptor = (isStatic ?
new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));
}
// Choose a "direct to target" dispatcher (used for
// unadvised calls to static targets that cannot return this).
Callback targetDispatcher = (isStatic ?
new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());
// 回调集合。其中包含aopInterceptor 中包含了 Aspect 的增强
// advisedDispatcher 用于判断如果method是Advised.class声明的,则使用AdvisedDispatcher进行分发
Callback[] mainCallbacks = new Callback[] {
aopInterceptor, // for normal advice
targetInterceptor, // invoke target without considering advice, if optimized
new SerializableNoOp(), // no override for methods mapped to this
targetDispatcher, this.advisedDispatcher,
new EqualsInterceptor(this.advised),
new HashCodeInterceptor(this.advised)
};
Callback[] callbacks;
// 如果类是静态 && 配置冻结。则准备做一些优化策略
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = new HashMap<>(methods.length);
// TODO: small memory optimization here (can skip creation for methods with no advice)
// 遍历所有的方法
for (int x = 0; x < methods.length; x++) {
Method method = methods[x];
// 获取适用于当前方法的拦截器和动态拦截建议
List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);
// 封装成 callback
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
// 保存,此时的key 为 method, value 为当前方法适用的增强。
this.fixedInterceptorMap.put(method, x);
}
// Now copy both the callbacks from mainCallbacks
// and fixedCallbacks into the callbacks array.
callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
this.fixedInterceptorOffset = mainCallbacks.length;
}
else {
callbacks = mainCallbacks;
}
return callbacks;
} 这里我们注意 Callback数组的组成:Callback数组是由 mainCallbacks + fixedInterceptorMap 组成。mainCallbacks 数组如下,为固定的七个。具体我们后面分析。
Callback[] mainCallbacks = new Callback[] {
aopInterceptor, // for normal advice
targetInterceptor, // invoke target without considering advice, if optimized
new SerializableNoOp(), // no override for methods mapped to this
targetDispatcher, this.advisedDispatcher,
new EqualsInterceptor(this.advised),
new HashCodeInterceptor(this.advised)
};这里的所说的静态是 根据 TargetSource#isStatic 方法判断,标志用户返回当前bean是否为静态的,比如常见的单例bean就是静态的,而原型模式下就是动态的。这里这个方法的主要作用是,对于静态的bean,spring是会对其进行缓存的,在多次使用TargetSource获取目标bean对象的时候,其获取的总是同一个对象,通过这种方式提高效率。
ProxyCallbackFilter 是 CglibAopProxy 的内部类,用来作为 Cglib CallBack 过滤器,在不同的场景下选择不同的 Callback执行增强策略。下面我们来看看 ProxyCallbackFilter#accept 的具体实现 :
// Constants for CGLIB callback array indices
// 这里是 Callback 数组的下标。
private static final int AOP_PROXY = 0;
private static final int INVOKE_TARGET = 1;
private static final int NO_OVERRIDE = 2;
private static final int DISPATCH_TARGET = 3;
private static final int DISPATCH_ADVISED = 4;
private static final int INVOKE_EQUALS = 5;
private static final int INVOKE_HASHCODE = 6;
private static class ProxyCallbackFilter implements CallbackFilter {
// 返回是 Callback 数组的下标
@Override
public int accept(Method method) {
// 1. 如果当前方法被 final 修饰,则不代理该方法
if (AopUtils.isFinalizeMethod(method)) {
logger.trace("Found finalize() method - using NO_OVERRIDE");
return NO_OVERRIDE;
}
// 2. 如果当前方法不透明 && 该方法是 Advised 接口声明的方法
if (!this.advised.isOpaque() && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
return DISPATCH_ADVISED;
}
// We must always proxy equals, to direct calls to this.
// 3. equals 方法
if (AopUtils.isEqualsMethod(method)) {
return INVOKE_EQUALS;
}
// We must always calculate hashCode based on the proxy.
// 4. hashcode 方法
if (AopUtils.isHashCodeMethod(method)) {
return INVOKE_HASHCODE;
}
// 获取代理目标类的 Class
Class<?> targetClass = this.advised.getTargetClass();
// Proxy is not yet available, but that shouldn't matter.
// 获取适用于当前类的 拦截器和动态拦截建议
List<?> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
boolean haveAdvice = !chain.isEmpty();
boolean exposeProxy = this.advised.isExposeProxy();
boolean isStatic = this.advised.getTargetSource().isStatic();
boolean isFrozen = this.advised.isFrozen();
// 5. 如果存在适用于当前类的拦截器和建议 || 配置没有被冻结
if (haveAdvice || !isFrozen) {
// If exposing the proxy, then AOP_PROXY must be used.
// 5.1 暴露代理类
if (exposeProxy) {
return AOP_PROXY;
}
// 5.2 类为静态 && 配置冻结 && 固定拦截器中保存了该方法的配置
// 检查是否有固定的拦截器来服务这个方法, 这里使用了 fixedInterceptorMap 做了一些优化
// fixedInterceptorMap key 为 Method, value 为 Integer 保存了拦截器下标。这里针对某些方法固定使用某个拦截器,不需要再动态匹配。
if (isStatic && isFrozen && this.fixedInterceptorMap.containsKey(method)) {
int index = this.fixedInterceptorMap.get(method);
return (index + this.fixedInterceptorOffset);
}
else {
// 5.3 否则还是使用 AOP_PROXY
return AOP_PROXY;
}
}
else {// 6. 到这里说明当前方法没有建议 && 配置冻结
// 6.1. 暴露当前代理类 && 代理类不是静态
if (exposeProxy || !isStatic) {
return INVOKE_TARGET;
}
// 6.2. 如果方法返回类型还是代理类类型
Class<?> returnType = method.getReturnType();
if (targetClass != null && returnType.isAssignableFrom(targetClass)) {
return INVOKE_TARGET;
}
else {
// 6.3 DISPATCH_TARGET
return DISPATCH_TARGET;
}
}
}这里总结如下:
上面我们看到 Cglib 默认的 mainCallbacks 如下:
Callback[] mainCallbacks = new Callback[] {
aopInterceptor, // for normal advice
targetInterceptor, // invoke target without considering advice, if optimized
new SerializableNoOp(), // no override for methods mapped to this
targetDispatcher, this.advisedDispatcher,
new EqualsInterceptor(this.advised),
new HashCodeInterceptor(this.advised)
};下面我们逐一来看:
aopInterceptor 的实现类是 DynamicAdvisedInterceptor,实现了MethodInterceptor 接口 用来处理常规的代理逻辑。结构如下:
我们直接来看看 DynamicAdvisedInterceptor#intercept 的具体实现,如下:
@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
// 获取目标数据
TargetSource targetSource = this.advised.getTargetSource();
try {
// 如果暴露代理对象,则设置到全局上下文中
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);
// 1. 获取 适用于当前类的当前方法的 获取拦截器和动态拦截建议
List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// 如果没有建议链则说明对该方法不需要增强,直接调用即可
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
// 即当前 args 的参数类型可能与实际方法调用的类型有些区别,这里转换成实际方法的参数类型。特别是,如果给定的可变参数数组与方法中声明的可变参数的数组类型不匹配。
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
// 调用目标类的目标方法
retVal = methodProxy.invoke(target, argsToUse);
}
else {
// We need to create a method invocation...
// 2. 创建一个 方法调用类,里面封装了相关信息,然后通过 proceed 方法调用
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
// 处理返回值。 即,如果返回值还是 target。则替换为 代理的proxy
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
} 注释已经写的比较清楚,这里我们关注下面两点:
ProxyFactory#getInterceptorsAndDynamicInterceptionAdvice 是获取当前方法的 拦截器和动态拦截建议,在上面也多次调用。其实现在 AdvisedSupport#getInterceptorsAndDynamicInterceptionAdvice 中,如下:
// 当前 this 为 ProxyFactory,所以这里的缓存是作用域是在 ProxyFactory中,如果换一个 ProxyFactory则需要重新加载一次。
public List getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
// 生成方法的key
MethodCacheKey cacheKey = new MethodCacheKey(method);
// 从缓存中获取该方法的 拦截器和动态拦截建议
List cached = this.methodCache.get(cacheKey);
if (cached == null) {
// 缓存没有命中则重新获取
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
// 将获取到的 拦截器和动态拦截建议 放入缓存中。
this.methodCache.put(cacheKey, cached);
}
return cached;
} 这里的 this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice 调用的是 DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice,其实现如下:
@Override
public List getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, @Nullable Class<?> targetClass) {
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
Advisor[] advisors = config.getAdvisors();
List interceptorList = new ArrayList<>(advisors.length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
Boolean hasIntroductions = null;
// 遍历所有的 Advisor,这里的 Advisor 是 ProxyFactory 中保存的
for (Advisor advisor : advisors) {
/******* 1. PointcutAdvisor 顾问类型的处理 *******/
// 如果是切点顾问
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
// 如果经过 预过滤 || 当前顾问 匹配当前类
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
// 判断当前方法是否匹配
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
boolean match;
if (mm instanceof IntroductionAwareMethodMatcher) {
if (hasIntroductions == null) {
hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
}
match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
}
else {
match = mm.matches(method, actualClass);
}
// 如果方法也匹配,则认为当前顾问适用于当前方法
if (match) {
// 获取顾问中的 方法拦截器。这里会将部分不合适的类型转换为合适的拦截器
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
// runtime 为 true, 表明是动态调用,即每次调用都需要执行一次判断。
if (mm.isRuntime()) {
// 动态调用将 拦截器包装成 InterceptorAndDynamicMethodMatcher
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
// 否则直接添加
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
else if (advisor instanceof IntroductionAdvisor) {
/******* 2. IntroductionAdvisor 顾问类型的处理 *******/
// 如果是引介顾问类型
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
// 预过滤 || 调用类匹配
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
// 直接添加
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
else {
/******* 3. 其他顾问类型的处理 *******/
// 直接添加
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
// 返回拦截器集合
return interceptorList;
} 上面的逻辑还是比较清楚,如下:
CglibMethodInvocation#proceed 调用其父类方法 ReflectiveMethodInvocation#proceed,作用为 执行了过滤器链流程,其实现如下:
@Override
@Nullable
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
// 如果所有拦截器执行结束,调用真正的方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// 获取下一个拦截器
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
// 如果是动态拦截器
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
// 判断调用是否匹配,如果匹配则调用拦截器方法
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
// 否则递归执行下一个拦截器
return proceed();
}
}
else {
// 非动态调用直接调用拦截器方法。
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}ProxyFactory#getInterceptorsAndDynamicInterceptionAdvice 返回的拦截器集合保存到了 interceptorsAndDynamicMethodMatchers 中, currentInterceptorIndex 记录执行到哪个拦截器。
其逻辑简述如下:
targetInterceptor 实现了 MethodInterceptor 接口,当方法没有适用拦截器和动态拦截建议 则可能使用该拦截器。aopInterceptor 在不同的情况下有不同的实现类,其规则如下:
org.springframework.aop.framework.CglibAopProxy#getCallbacks
// 如果需要暴露代理类,则需要在执行前将代理类保存到 AOP上下文 中,
// 而 StaticUnadvisedExposedInterceptor 和 DynamicUnadvisedExposedInterceptor 中完成了此操作。
if (exposeProxy) {
targetInterceptor = (isStatic ?
// 如果是静态,直接将 getTarget 对象传入,因为对象不可变。否则传入 TargetSource 由拦截器在内部获取。
new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()));
}
else {
targetInterceptor = (isStatic ?
new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));
}即:
@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
try {
// 切换当前AOP上下文的 代理类对象
oldProxy = AopContext.setCurrentProxy(proxy);
Object retVal = methodProxy.invoke(this.target, args);
return processReturnType(proxy, this.target, method, retVal);
}
finally {
// 重置回上下文对象
AopContext.setCurrentProxy(oldProxy);
}
}2.如果 exposeProxy = true && 代理类不是静态:DynamicUnadvisedExposedInterceptor
@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
Object target = this.targetSource.getTarget();
try {
oldProxy = AopContext.setCurrentProxy(proxy);
Object retVal = methodProxy.invoke(target, args);
return processReturnType(proxy, target, method, retVal);
}
finally {
AopContext.setCurrentProxy(oldProxy);
if (target != null) {
this.targetSource.releaseTarget(target);
}
}
}3.如果 exposeProxy = false && 代理类是静态: StaticUnadvisedInterceptor
@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object retVal = methodProxy.invoke(this.target, args);
return processReturnType(proxy, this.target, method, retVal);
}4.如果 exposeProxy = false && 代理类不是静态:DynamicUnadvisedInterceptor
@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object target = this.targetSource.getTarget();
try {
Object retVal = methodProxy.invoke(target, args);
return processReturnType(proxy, target, method, retVal);
}
finally {
if (target != null) {
this.targetSource.releaseTarget(target);
}
}
}注: 这里的所说的静态是 根据 TargetSource#isStatic 方法判断,标志用户返回当前bean是否为静态的,比如常见的单例bean就是静态的,而原型模式下就是动态的。这里这个方法的主要作用是,对于静态的bean,spring是会对其进行缓存的,在多次使用TargetSource获取目标bean对象的时候,其获取的总是同一个对象,通过这种方式提高效率。
SerializableNoOp 没有做任何事。用于无需代理或无法代理的方法。
public static class SerializableNoOp implements NoOp, Serializable {
}StaticDispatcher 是静态类情况下的懒加载策略,其实现如下:
private static class StaticDispatcher implements Dispatcher, Serializable {
@Nullable
private final Object target;
public StaticDispatcher(@Nullable Object target) {
this.target = target;
}
@Override
@Nullable
public Object loadObject() {
return this.target;
}
}AdvisedDispatcher 仍为懒得加载策略。 调用时机为代理类调用的是 Advised 接口声明的方法时,其实现如下:
/**
* Dispatcher for any methods declared on the Advised class.
*/
private static class AdvisedDispatcher implements Dispatcher, Serializable {
private final AdvisedSupport advised;
public AdvisedDispatcher(AdvisedSupport advised) {
this.advised = advised;
}
@Override
public Object loadObject() {
return this.advised;
}
}EqualsInterceptor 用于处理 equals 方法的调用,其实现如下:
private static class EqualsInterceptor implements MethodInterceptor, Serializable {
private final AdvisedSupport advised;
public EqualsInterceptor(AdvisedSupport advised) {
this.advised = advised;
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) {
Object other = args[0];
if (proxy == other) {
return true;
}
if (other instanceof Factory) {
Callback callback = ((Factory) other).getCallback(INVOKE_EQUALS);
if (!(callback instanceof EqualsInterceptor)) {
return false;
}
AdvisedSupport otherAdvised = ((EqualsInterceptor) callback).advised;
return AopProxyUtils.equalsInProxy(this.advised, otherAdvised);
}
else {
return false;
}
}
}HashCodeInterceptor用于处理 hashcode 方法的调用,其实现如下:
private static class HashCodeInterceptor implements MethodInterceptor, Serializable {
private final AdvisedSupport advised;
public HashCodeInterceptor(AdvisedSupport advised) {
this.advised = advised;
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) {
return CglibAopProxy.class.hashCode() * 13 + this.advised.getTargetSource().hashCode();
}
}我们这里总结一下Spring Aop Cglib 的代理过程:
@EnableAspectJAutoProxy 注解通过@Import(AspectJAutoProxyRegistrar.class)引入了AspectJAutoProxyRegistrar类,实现了SmartInstantiationAwareBeanPostProcessor接口, 所以会在Bean创建的时候,发现并记录了合适的所有的Advisor并进行拦截代理。
注册bean的后置处理器。
完成其他bean的注册。
try{
前置通知@Before
目标方法的执行
返回通知@AfterReturning
}catch(){
异常通知@AfterThrowing
}finally{
后置通知 @After
}环绕着通知的执行顺序
@Around("execution(* com.hsf.spring.aop.HelloService.sayHello(..))")
public void around(ProceedingJoinPoint joinPoint) {
try {
System.out.println("【环绕前置通知】 around before");
joinPoint.proceed(); // 放行切点的方法,不放行则会阻塞调用
System.out.println("【环绕返回通知】around after");
} catch (Throwable throwable) {
throwable.printStackTrace();
System.out.println("【环绕异常通知】 around throwable");
}finally {
System.out.println("【环绕后置通知】 around throwable");
}
}AbstractBeanDefinition的构造器打断点,就能知道容器中的bean定义信息,Spring也可能在底层直接new对象注册进去。最好给refresh()十二大步的最后一步打上断点,在debug控制台看有哪些没见过的组件。单独分析他们即可
每一个功能的开启,要么写配置,要么注解。@EnableXXX 开启 xxx功能的注解。这个注解很重要。
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy { }它是BeanPostProcessor
AnnotationAwareAspectJAutoProxyCreator 第一次运行的时候分析组装好了切面、增强器(通知方法)的所有信息;
| 留言与评论(共有 0 条评论) “” |