spring的aop是使用代理對象
兩種代理方式
jdk動態代理
cglib代理
jdk動態代理爲例,理解代理的調用過程。spring
JdkDynamicAopProxy.(Object proxy, Method method, Object[] args)
判斷是equals方法,不加強,直接返回。緩存
if (!this.equalsDefined && AopUtils.isEqualsMethod(method))
判斷是hashCode方法,直接返回。app
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method))
...ide
是否須要暴露代理對象this
if (this.advised.exposeProxy)
獲取方法上的攔截器鏈lua
// Get the interception chain for this method. List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
緩存中取攔截器鏈,緩存中有攔截器鏈直接返回,緩衝中沒有就調用etInterceptorsAndDynamicInterceptionAdvice方法去獲取,並把獲取到的攔截器鏈放入緩存中。spa
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) { MethodCacheKey cacheKey = new MethodCacheKey(method); List<Object> cached = this.methodCache.get(cacheKey); if (cached == null) { cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice( this, method, targetClass); this.methodCache.put(cacheKey, cached); } return cached; }
攔截器鏈爲空,直接經過反射調用方法代理
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); }
攔截器鏈不爲空,建立反射的方法調用code
// We need to create a method invocation... invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); // Proceed to the joinpoint through the interceptor chain. retVal = invocation.proceed();
建立對象過程對象
//invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); //具體的構造方法 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; }
重點步驟、加強的實現、攔截器鏈的調用。所有加強都會在這裏實現完,返回。before、after、throw、環繞。
@Override public Object proceed() throws Throwable { // 從-1開始。We start with an index of -1 and increment early. //判斷攔截器鏈執行完畢 if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { return invokeJoinpoint(); } // 從攔截器鏈中拿出一個攔截器、並把下標++1 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. return ((MethodInterceptor) //每次下標會++,因此每次在這個地方實現不一樣的加強 interceptorOrInterceptionAdvice).invoke(this); } }