Spring系列之AopProxy-JdkDynamicAopProxy

/**
* 查找被代理目标源接口是否已经定义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、静态方法匹配拦截器,进行增强处理


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值