溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Spring Framework中DefaultAdvisorChainFactory類案例分析

發(fā)布時間:2021-11-16 09:44:49 來源:億速云 閱讀:136 作者:iii 欄目:大數(shù)據(jù)

這篇文章主要講解了“Spring Framework中DefaultAdvisorChainFactory類案例分析”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Spring Framework中DefaultAdvisorChainFactory類案例分析”吧!

    Spring版本是5.0.4.release. 

    JdkDynamicAopProxy中使用到了攔截器鏈,如下List-1,advised是ProxyFactory,而方法getInterceptorsAndDynamicInterceptionAdvice則是在其父類AdvisedSupport中。

    List-1

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		...
		// Get the interception chain for this method.
		List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
		...
}

    如下List-2,advisorChainFactory是DefaultAdvisorChainFactory

    List-2

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable 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;
}

     getInterceptorsAndDynamicInterceptionAdvice的方法實現(xiàn)如下List-3所示,會將Advisor轉(zhuǎn)換為Interceptor,List-3中的registry是DefaultAdvisorAdapterRegistry。

    List-3

public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializable {

	@Override
	public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
			Advised config, Method method, @Nullable Class<?> targetClass) {
			...
			Interceptor[] interceptors = registry.getInterceptors(advisor);
			...		

		return interceptorList;
	}
	...

    如下List-4所示,構(gòu)造方法中注冊了Adapter,而后getInterceptors方法中會使用模板模式將advisor中的advice轉(zhuǎn)換為MethodInterceptor。

    List-4

public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {

	private final List<AdvisorAdapter> adapters = new ArrayList<>(3);

	public DefaultAdvisorAdapterRegistry() {
		registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
		registerAdvisorAdapter(new AfterReturningAdviceAdapter());
		registerAdvisorAdapter(new ThrowsAdviceAdapter());
	}

	@Override
	public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
		List<MethodInterceptor> interceptors = new ArrayList<>(3);
		Advice advice = advisor.getAdvice();
		if (advice instanceof MethodInterceptor) {
			interceptors.add((MethodInterceptor) advice);
		}
		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]);
	}
	...

    來看個例子,如下List-5所示,MethodBeforeAdviceAdapter的supportsAdvice方法中判斷是否是MethodBeforeAdvice;getInterceptor方法中將advice封裝到MethodBeforeAdviceInterceptor中。

    List-5

class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {

	@Override
	public boolean supportsAdvice(Advice advice) {
		return (advice instanceof MethodBeforeAdvice);
	}

	@Override
	public MethodInterceptor getInterceptor(Advisor advisor) {
		MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
		return new MethodBeforeAdviceInterceptor(advice);
	}
}

    MethodBeforeAdviceInterceptor的代碼如下,比較簡單,主要是invoke方法,會先調(diào)用MethodBeforeAdvice的before方法,之后才會執(zhí)行MethodInvocation的invoke方法。

    List-6

public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {
	private final MethodBeforeAdvice advice;

	public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
		Assert.notNull(advice, "Advice must not be null");
		this.advice = advice;
	}

	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
		return mi.proceed();
	}
}

    整體來看DefaultAdvisorChainFactory會將我們的advice轉(zhuǎn)換為MethodInerceptor,而不同的Advice實現(xiàn),對應(yīng)的MethodInterceptor實現(xiàn)也不一樣,進(jìn)而實現(xiàn)Before、After的攔截實現(xiàn)。

    從Spring容器中獲取bean的時候,用于這個bean的攔截器就構(gòu)造好,且與這個目標(biāo)類封裝在一起,之后當(dāng)調(diào)用這個目標(biāo)類的方法時,就會再次構(gòu)造攔截器鏈,為什么會再次構(gòu)造攔截器鏈?zhǔn)且驗橛行r截器只作用與目標(biāo)類的部分方法,不過這個基于方法層面的攔截器還是做了緩存的。

感謝各位的閱讀,以上就是“Spring Framework中DefaultAdvisorChainFactory類案例分析”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對Spring Framework中DefaultAdvisorChainFactory類案例分析這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI