spring AOP 源碼淺析
概述
AbstractAutoProxyCreator
通過postProcessAfterInitialization
實現(xiàn)AOP功能藤乙。
源碼部分
- AbstractAutoProxyCreator
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// getAdvicesAndAdvisorsForBean 由子類重寫
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
- 子類 AbstractAdvisorAutoProxyCreator 中的 getAdvicesAndAdvisorsForBean
@Override
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// BeanFacrory 中所有 Advisor 的實現(xiàn)
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 有資格的 Advisor
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
protected List<Advisor> findCandidateAdvisors() {
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
return this.advisorRetrievalHelper.findAdvisorBeans();
}
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
}
finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
-
關于createProxy
ProxyFactory
對象中有要代理的bean和這個Bean上的advisor-
Bean使用哪種代理
- 當Bean實現(xiàn)接口時别垮,Spring就會用JDK的動態(tài)代理蜡饵。
- 當Bean沒有實現(xiàn)接口時囤捻,Spring會自動使用CGlib實現(xiàn)湃交,但是前提是項目中導入了CGlib的相關依賴,否則Spring只能使用JDK來代理那些沒有實現(xiàn)接口的類坟漱,這樣生成的代理類會報錯。
-
AopProxy
有兩個實現(xiàn)類JdkDynamicAopProxy
和CglibAopProxy
更哄。都是構造ReflectiveMethodInvocation.proceed()
芋齿。-
JdkDynamicAopProxy
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); retVal = invocation.proceed();
-
CglibAopProxy
// CglibMethodInvocation 繼承于 ReflectiveMethodInvocation retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
-
ReflectiveMethodInvocation.proceed()
public Object proceed() throws Throwable {
// 當所有攔截器都執(zhí)行后,調(diào)用目標類的目標方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// 動態(tài)攔截器
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 {
// MethodInterceptor的實現(xiàn)類在處理完自己的邏輯后成翩,還是會調(diào)用procee(),傳入this就是為了達到這個目的
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}