?????Java是面向?qū)ο蟮木幊陶Z言,整個程序的執(zhí)行是方法縱向的調(diào)用完成,Aop是面向切面的編程思想,是對面向?qū)ο蟮囊粋€補充。Aop面向切面的思想是針對方法進行編程,依賴動態(tài)代理來實現(xiàn)對方法執(zhí)行的前后注入業(yè)務(wù)邏輯。簡而言之,spring aop是面向切面的編程思想,輔佐以動態(tài)代理的實現(xiàn)來完成。
????下面以ProxyFactoryBean的getObject為切入點,來分析spring aop的實現(xiàn)原理。
獲取通知器鏈
?????從ProxyFactoryBean的getObject方法中可以看到,initializeAdvisorChain初始化通知器鏈,這個是通過讀取interceptorNames的配置屬性獲取的,然后把獲取到的所有通知器添加到通知器鏈中,這里是按配置的順序進行添加的。最后是把所有通知器鏈保存到advisors屬性中。
public Object getObject() throws BeansException {
//從ProxyFactoryBean的配置中獲取所有的advisor信息
initializeAdvisorChain();
if (isSingleton()) {
//獲取代理對象
return getSingletonInstance();
}
// ...
}
private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
if (!ObjectUtils.isEmpty(this.interceptorNames)) {
// ...
for (String name : this.interceptorNames) {
if (name.endsWith(GLOBAL_SUFFIX)) {
addGlobalAdvisors((ListableBeanFactory) this.beanFactory,
name.substring(0, name.length() - GLOBAL_SUFFIX.length()));
}
else {
Object advice;
if (this.singleton || this.beanFactory.isSingleton(name)) {
//這里從spring ioc容器中獲取通知bean
advice = this.beanFactory.getBean(name);
}
else {
advice = new PrototypePlaceholderAdvisor(name);
}
//把獲取到的通知添加到通知器鏈中,這里是按序添加的
addAdvisorOnChainCreation(advice);
}
}
}
this.advisorChainInitialized = true;
}
代理對象的生成
?????aop代理對象的生成是委托給AopProxy來進行代理對象的生成。
private synchronized Object getSingletonInstance() {
if (this.singletonInstance == null) {
//生成一個aop代理對象
this.singletonInstance = getProxy(createAopProxy());
}
return this.singletonInstance;
}
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//配置了isProxyTargetClass屬性或者沒有實現(xiàn)接口就使用ObjenesisCglibAopProxy去生成代理對象,否則就使用JdkDynamicAopProxy生成代理對象
if (!NativeDetector.inNativeImage() &&
(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
}
?????這里可以看到,spring把代理對象的生成是交給了AopProxy接口,通過AopProxy來解耦了代理對象的生成。在配置了isOptimize或isProxyTargetClass的時候,并且目標(biāo)對象不是實現(xiàn)接口的形式,就采用ObjenesisCglibAopProxy來生成代理對象,否則就使用JdkDynamicAopProxy去生成代理對象。對于代理對象這里是動態(tài)代理設(shè)計模式的使用,對于動態(tài)代理對象這里不進行解釋,以JdkDynamicAopProxy為例來看看代理對象的生成過程。
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
}
}
?????在代理模式中,Proxy生成代理對象的時候,需要傳入類加載器、目標(biāo)對象實現(xiàn)的接口和觸發(fā)器。代理對象生成后,對目標(biāo)對象所有的方法調(diào)用都會交給InvocationHandler進行處理,都會觸發(fā)InvovationHandler接口invoke方法的調(diào)用。JdkDynamicAopProxy實現(xiàn)了InvocationHandler接口,所以這里在生成代理對象的時候,把自己作為InvocationHandler參數(shù)傳進去了。
?????以上是為實現(xiàn)spring aop進行的基礎(chǔ)處理和鋪墊:
- 讀取配置的通知器到advisors通知器鏈中
- 代理對象的生成
?????接下來看看在實際方法調(diào)用的過程中,aop是怎么對運行的方法進行攔截處理的。對目標(biāo)方法的調(diào)用最終都會轉(zhuǎn)交給InvocationHandler的invoke方法的處理,以這個為入口進行分析。
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
// ...
//獲取通知器鏈
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
if (chain.isEmpty()) {
//如果通知器鏈為空,直接執(zhí)行目標(biāo)方法
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
//通知器鏈不為空,包裝成ReflectiveMethodInvocation進行調(diào)用
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
retVal = invocation.proceed();
}
return retVal;
}
}
?????這里是先獲取當(dāng)前方法的通知器鏈,然后把通知器鏈包裝成ReflectiveMethodInvocation進行調(diào)用。
通知器鏈如何獲取
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;
}
public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializable {
@Override
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, @Nullable Class<?> targetClass) {
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
Advisor[] advisors = config.getAdvisors();
List<Object> interceptorList = new ArrayList<>(advisors.length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
Boolean hasIntroductions = null;
for (Advisor advisor : advisors) {
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
//這里用來判斷通知器對當(dāng)前方法是否匹配
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
boolean match;
if (mm instanceof IntroductionAwareMethodMatcher) {
if (hasIntroductions == null) {
hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
}
match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
}
else {
match = mm.matches(method, actualClass);
}
if (match) {
//這里是把通知轉(zhuǎn)換成MethodInterceptor
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
if (mm.isRuntime()) {
for (MethodInterceptor interceptor : interceptors) {
//然后把包裝后的通知和方法匹配器包裝起來放到攔截器鏈中
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
}
return interceptorList;
}
}
?????可以看到在獲取通知器鏈的時候,是使用DefaultAdvisorChainFactory來進行獲取的。
- 在初始化通知器鏈的時候,已經(jīng)把配置的通知器添加到通知器鏈中了。
- 根據(jù)通知器鏈,通過MethodMatcher來判斷通知器對當(dāng)前方法是否匹配
- 對于匹配的通知器,這里把通知器和MethodMatcher包裝成InterceptorAndDynamicMethodMatcher轉(zhuǎn)換成MethodInterceptor添加到攔截器鏈中。
看看通知器適配成攔截器的過程
?????DefaultAdvisorAdapterRegistry是用來把advisor轉(zhuǎn)換成MethodInterceptor。
public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
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]);
}
}
?????在DefaultAdvisorAdapterRegistry實例化的時候,添加了3個適配器,由這3個適配器來具體完成對不同的advisor完成Interceptor轉(zhuǎn)換。下面以MethodBeforeAdviceAdapter來分析:
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);
}
}
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {
@Override
@Nullable
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
return mi.proceed();
}
}
?????適配器把Advisor轉(zhuǎn)換成MethodBeforeAdviceInterceptor攔截器。
獲取完攔截器,看看在方法調(diào)用實際運行的時候,攔截器鏈?zhǔn)窃趺雌鹱饔玫摹?/h5>
MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();
public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
public Object proceed() throws Throwable {
//如果通知器鏈為空,直接調(diào)用目標(biāo)方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
//這里從通知器鏈開始處進行調(diào)用
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
//如果當(dāng)前通知器匹配當(dāng)前調(diào)用的方法,就執(zhí)行攔截器邏輯
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
//攔截器不匹配的話,沿著攔截器鏈調(diào)用下一個攔截器
return proceed();
}
}
else {
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
}
MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();
public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
public Object proceed() throws Throwable {
//如果通知器鏈為空,直接調(diào)用目標(biāo)方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
//這里從通知器鏈開始處進行調(diào)用
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
//如果當(dāng)前通知器匹配當(dāng)前調(diào)用的方法,就執(zhí)行攔截器邏輯
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
//攔截器不匹配的話,沿著攔截器鏈調(diào)用下一個攔截器
return proceed();
}
}
else {
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
}
?????沿著攔截器鏈開始,一個個遍歷執(zhí)行攔截器中的所有攔截器,這里就是前面從通知器適配轉(zhuǎn)換的MethodBeforeAdviceInterceptor攔截器等。
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {
@Override
@Nullable
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
return mi.proceed();
}
}
?????這里就回到了我們自己寫的業(yè)務(wù)通知邏輯。cglib生成的代理對象執(zhí)行過程和jdk執(zhí)行過程沒有太大的區(qū)別。