Spring AOP ProxyFactoryBean源码笔记
2019-08-08 本文已影响0人
丶含光
AopProxy getProxy()
方法获取到的代理分为Jdk代理JdkDynamicAopProxy
或者Cglib代理ObjenesisCglibAopProxy
。代理在生成代理对象时,设置了对应的回调入口。
- Jdk是
JdkDynamicAopProxy
中用Proxy.newProxyInstance
来生成代理对象,对应的回调入口为JdkDynamicAopProxy invoke()
方法。 - Cglib是在
ObjenesisCglibAopProxy
的父类CglibAopProxy
中配置了Enhancer
来创建代理对象,Enhancer
上的回调为DynamicAdvisedInterceptor
, 实际的回调入口为DynamicAdvisedInterceptor intercept()
方法
代理类的调用过程:
- Jdk的回调
JdkDynamicAopProxy invoke()
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
...
// 顺序1
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
throw new AopConfigException("No advisors and no TargetSource specified");
}
this.advised = config;
}
...
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation;
Object oldProxy = null;
boolean setProxyContext = false;
// 顺序1
// 在创建Jdk代理的时候,调用了JdkDynamicAopProxy的构造器,new JdkDynamicAopProxy(config)。
// config即ProxyFactoryBean,保存在JdkDynamicAopProxy的advised属性上。
// 从ProxyFactoryBean上获取包装后的目标对象
TargetSource targetSource = this.advised.targetSource;
Class<?> targetClass = null;
Object target = null;
try {
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
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)) {
// 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;
}
// May be null. Get as late as possible to minimize the time we "own" the target,
// in case it comes from a pool.
// 真正的目标对象
target = targetSource.getTarget();
if (target != null) {
targetClass = target.getClass();
}
// Get the interception chain for this method.
// 顺序2
// 获取拦截器链
// 调用的是JdkDynamicAopProxy的基类AdvisedSupport的getInterceptorsAndDynamicInterceptionAdvice()方法
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...
// 顺序6
// 构造ReflectiveMethodInvocation
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
// 顺序7
// 调用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);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
AdvisedSupport getInterceptorsAndDynamicInterceptionAdvice()
public class AdvisedSupport extends ProxyConfig implements Advised {
...
AdvisorChainFactory advisorChainFactory = new DefaultAdvisorChainFactory();
...
private transient Map<MethodCacheKey, List<Object>> methodCache;
...
private void initMethodCache() {
this.methodCache = new ConcurrentHashMap<MethodCacheKey, List<Object>>(32);
}
...
// 顺序2
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
MethodCacheKey cacheKey = new MethodCacheKey(method);
// 尝试从缓存中获取拦截器
List<Object> cached = this.methodCache.get(cacheKey);
if (cached == null) {
// 顺序3
// 如果缓存中获取不到
// this.advisorChainFactory为DefaultAdvisorChainFactory,进入其getInterceptorsAndDynamicInterceptionAdvice()方法
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
this.methodCache.put(cacheKey, cached);
}
return cached;
}
DefaultAdvisorChainFactory getInterceptorsAndDynamicInterceptionAdvice()
public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializable {
...
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
...
// 顺序3
@Override
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, Class<?> targetClass) {
// This is somewhat tricky... We have to process introductions first,
// but we need to preserve order in the ultimate list.
List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
// 遍历通知器
for (Advisor advisor : config.getAdvisors()) {
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
// DefaultPointcutAdvisor的matches()始终返回true
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
// 顺序4
// 获取当前通知器的所有拦截器。一个通知器可能前置、后置和异常多个拦截器
// registry为GlobalAdvisorAdapterRegistry.getInstance();
// 在上一篇ProxyFactoryBean初始化过程中,已经创建了DefaultAdvisorAdapterRegistry
// 并在其构造器中初始化了前置、后置和异常通知适配器
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
// 拿到通知器的切点 再根据切点拿到方法匹配规则
// demo中的通知器类型均为DefaultPointcutAdvisor,匹配规则始终为true(所有方法均匹配)
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
if (mm.isRuntime()) {
// Creating a new object instance in the getInterceptors() method
// isn't a problem as we normally cache created chains.
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
// 收集了所有的拦截器
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
else if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
else {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
return interceptorList;
}
private static boolean hasMatchingIntroductions(Advised config, Class<?> actualClass) {
for (int i = 0; i < config.getAdvisors().length; i++) {
Advisor advisor = config.getAdvisors()[i];
if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (ia.getClassFilter().matches(actualClass)) {
return true;
}
}
}
return false;
}
DefaultAdvisorAdapterRegistry getInterceptors()
public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
...
// 顺序4
@Override
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
// 从通知器中取出通知
Advice advice = advisor.getAdvice();
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
for (AdvisorAdapter adapter : this.adapters) {
// 逐个适配器判断是否适配当前通知
// 一个通知也可以同时适配多个适配器。例如一个类同时实现前置与后置拦截器的接口
if (adapter.supportsAdvice(advice)) {
// 顺序5
// 如果适配,用适配器与通知器构造对应的拦截器
// 例如AfterReturningAdviceInterceptor后置适配器
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
// 最终返回所有拦截器
return interceptors.toArray(new MethodInterceptor[interceptors.size()]);
}
AfterReturningAdviceAdapter
class AfterReturningAdviceAdapter implements AdvisorAdapter, Serializable {
...
// 顺序5 构造后置拦截器 返回顺序2
@Override
public MethodInterceptor getInterceptor(Advisor advisor) {
AfterReturningAdvice advice = (AfterReturningAdvice) advisor.getAdvice();
return new AfterReturningAdviceInterceptor(advice);
}
ReflectiveMethodInvocation
public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
...
// 顺序6
protected ReflectiveMethodInvocation(
Object proxy, Object target, Method method, Object[] arguments,
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;
}
...
// 顺序7
@Override
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;
if (dm.methodMatcher.matches(this.method, this.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 {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
// 在目标方法执行前
// 获取到拦截器链上的第一个拦截器
// 如果是前置拦截器,先执行前置拦截器的逻辑,然后执行目标方法(参考下面MethodBeforeAdviceInterceptor中的invoke()方法),此时并不是真正的执行目标方法,而是继续进入到ReflectiveMethodInvocation的proceed() 方法,获取下一个拦截器。
// 如果是后置拦截器,先执行目标方法(参考下面AfterReturningAdviceInterceptor中的invoke()方法),同样进入到proceed() 方法,获取下一个拦截器,待执行完下一个拦截器,再回来执行后置逻辑。
// 依次循环,直到所有的拦截器执行完,最终执行目标方法。
// 总的来说是所有前置拦截器中前置逻辑先执行,然后执行目标方法,最后执行所有后置拦截器的后置逻辑再执行。
// 异常拦截器的逻辑相似,用try catch包裹了目标方法的执行,在出现异常时执行织入的异常逻辑,然后将异常向上抛出。
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
MethodBeforeAdviceInterceptor invoke()
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
// 通知的before方法先执行 再执行目标方法
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
return mi.proceed();
}
AfterReturningAdviceInterceptor invoke()
public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
Object retVal = mi.proceed();
// 待目标方法执行完成,再执行通知的after方法
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}
- Cglib的回调
DynamicAdvisedInterceptor intercept()
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
...
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Class<?> targetClass = null;
Object target = null;
try {
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// May be null. Get as late as possible to minimize the time we
// "own" the target, in case it comes from a pool...
target = getTarget();
if (target != null) {
targetClass = target.getClass();
}
// 同上 获取拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// Check whether we only have one InvokerInterceptor: that is,
// no real advice, but just reflective invocation of the target.
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
// 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 = methodProxy.invoke(target, argsToUse);
}
else {
// We need to create a method invocation...
// 构造CglibMethodInvocation,然后执行proceed()方法。CglibMethodInvocation是ReflectiveMethodInvocation的子类,还是执行了ReflectiveMethodInvocation的proceed()方法,同上。
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null) {
releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
总结:
- 初始化通知器,将对ProxyFactory配置的所有通知(也可以是通知器)收集起来,即为目标对象配置的所有通知收集起来。
- 根据目标对象创建代理,Jdk代理或者Cglib代理。
- 根据代理创建代理对象,在创建代理对象时设置回调入口。
- 对目标方法的调用,实际是调用了代理对象的回调方法。例如
JdkDynamicAopProxy invoke()
和DynamicAdvisedInterceptor intercept()
- 拿到初始化中收集的通知器,从通知器中拿到切点,切点中再拿到方法匹配器,根据匹配规则,将应该为当前方法做的增强收集起来
- 最终构造
ReflectiveMethodInvocation
对象,执行proceed()
方法,先执行收集起来的前置通知,再执行目标方法,最后执行收集起来的后置通知。如果在目标方法执行过程中有发生异常,会执行收集的异常通知,再将异常向上抛出。