/**
* 查找被代理目标源接口是否已经定义equals和hashcode方法
*/
private void findDefinedEqualsAndHashCodeMethods(Class<?>[] proxiedInterfaces) {
for (Class<?> proxiedInterface : proxiedInterfaces) {
Method[] methods = proxiedInterface.getDeclaredMethods();
for (Method method : methods) {
if (AopUtils.isEqualsMethod(method)) {
this.equalsDefined = true;
}
if (AopUtils.isHashCodeMethod(method)) {
this.hashCodeDefined = true;
}
if (this.equalsDefined && this.hashCodeDefined) {
return;
}
}
}
}
===========================================================================
/**
* 相等意味着接口、切面和目标源(被代理目标源)是相等的* <p>比较对象可能是JDKDyjiAOPoServer实例本身,也可以是动态包装JDKDyjiAOPoServer实例的代理。
*/
@Override
public boolean equals(@Nullable Object other) {
if (other == this) {
return true;
}
if (other == null) {
return false;
}
JdkDynamicAopProxy otherProxy;
if (other instanceof JdkDynamicAopProxy) {
otherProxy = (JdkDynamicAopProxy) other;
}
else if (Proxy.isProxyClass(other.getClass())) {
InvocationHandler ih = Proxy.getInvocationHandler(other);
if (!(ih instanceof JdkDynamicAopProxy)) {
return false;
}
otherProxy = (JdkDynamicAopProxy) ih;
}
else {
// Not a valid comparison...
return false;
}
// If we get here, otherProxy is the other AopProxy.
return AopProxyUtils.equalsInProxy(this.advised, otherProxy.advised);
}
============================================================================================
/**
* 除非钩子方法抛出异常,否则调用方将完全看到目标抛出的异常。
*/
@Override
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation;Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Object target = null;
try {if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// 被代理对象未实现equals方法.
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// 被代理对象未实现hashCode方法。return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// 如果一个类的接口是Advised类,则spring 不会使用增强。而是直接通过反射方法进行调用
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);
// 获取方法的拦截器链
List<Object> chain= this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// Check whether we have any advice. If we don't, we can fallback on direct
// reflective invocation of the target, and avoid creating a MethodInvocation.
if (chain.isEmpty()) {
// We can skip creating a MethodInvocation: just invoke the target directly
// Note that the final invoker must be an InvokerInterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// We need to create a method invocation...
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// 通过拦截器链进入连接点即方法调用。
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);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
org.springframework.aop.framework.adapter.AdvisorAdapterRegistrationManager
Spring容器启动时将增强适配注册器注入到org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry中
org.springframework.aop.framework.AdvisedSupport
从缓存中获取当前调用方法的拦截器链,如果没有则调用AdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice方法获取
org.springframework.aop.framework.DefaultAdvisorChainFactory
判断是否有引介增强,获取当前调用方法匹配的增强拦截器链
org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry
获取增强对应的MethodInterceptor,默认有方法调用前增强适配器、方法调用后增强适配器、方法调抛出异常增强适配器,环绕增强、引介增强是MethodInterceptor不用转换。
org.springframework.aop.framework.adapter.MethodBeforeAdviceAdapter
将Advice转换成对应的MethodInterceptor
org.springframework.aop.framework.ReflectiveMethodInvocation
1、如果拦截器链为空,则直接通过反射进行方法调用,调用真正的被代理对象的方法
2、如果是动态方法匹配拦截器,匹配当前调用方法则进行强处理否则进入下一个拦截器
3、静态方法匹配拦截器,进行增强处理