上一節(jié)我們分析了Advisor的生成過(guò)程以及在Advisor中生成Advise的過(guò)程。接著上一節(jié)繼續(xù)我們看看挑出適用于目標(biāo)對(duì)象的Advisor:
private void addAdvisorsFromAspectInstanceFactory(MetadataAwareAspectInstanceFactory instanceFactory) {
//獲取Advisors集合
List<Advisor> advisors = this.aspectFactory.getAdvisors(instanceFactory);
//從中挑出適用于目標(biāo)對(duì)象的Advisor
advisors = AopUtils.findAdvisorsThatCanApply(advisors, getTargetClass());
AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(advisors);
//對(duì)獲取到的Advisor進(jìn)行排序
AnnotationAwareOrderComparator.sort(advisors);
//將獲取到Advisor添加到advisors集合中
addAdvisors(advisors);
}
2.3.1:addAdvisorsFromAspectInstanceFactory方法:
a、挑出適用于目標(biāo)對(duì)象的Advisor: AopUtils.findAdvisorsThatCanApply(advisors, getTargetClass());
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
//如果傳入的Advisor集合為空的話敬锐,直接返回這個(gè)空集合
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
//創(chuàng)建一個(gè)合適的Advisor的集合 eligible
List<Advisor> eligibleAdvisors = new LinkedList<Advisor>();
//循環(huán)所有的Advisor
for (Advisor candidate : candidateAdvisors) {
//如果Advisor是IntroductionAdvisor 引介增強(qiáng) 可以為目標(biāo)類 通過(guò)AOP的方式添加一些接口實(shí)現(xiàn)
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
//是否有引介增強(qiáng)
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
for (Advisor candidate : candidateAdvisors) {
//如果是IntroductionAdvisor類型的話 則直接跳過(guò)
if (candidate instanceof IntroductionAdvisor) {
// already processed
continue;
}
//判斷此Advisor是否適用于target
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
//如果是IntroductionAdvisor的話泪喊,則調(diào)用IntroductionAdvisor類型的實(shí)例進(jìn)行類的過(guò)濾
//這里是直接調(diào)用的ClassFilter的matches方法
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
}
//通常我們的Advisor都是PointcutAdvisor類型
else if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pca = (PointcutAdvisor) advisor;
//這里從Advisor中獲取Pointcut的實(shí)現(xiàn)類 這里是AspectJExpressionPointcut
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
// It doesn't have a pointcut so we assume it applies.
return true;
}
}
這里匹配的規(guī)則我們就不進(jìn)行深入了措译。
2.4:接著我們來(lái)看看代理對(duì)象的創(chuàng)建過(guò)程:
public class TestAop {
public static void main(String[] args) {
//手工創(chuàng)建一個(gè)實(shí)例(Target)
ProxyService aspectJService = new ProxyServiceImpl();
//使用AspectJ語(yǔ)法 自動(dòng)創(chuàng)建代理對(duì)象
AspectJProxyFactory aspectJProxyFactory = new AspectJProxyFactory(aspectJService);
//添加切面和通知類
aspectJProxyFactory.addAspect(AopAdviceConfig.class);
//創(chuàng)建代理對(duì)象
ProxyService proxyService = aspectJProxyFactory.getProxy();
//進(jìn)行方法調(diào)用
proxyService.testProxy();
}
}
a吗浩、創(chuàng)建代理aspectJProxyFactory.getProxy():
//通過(guò)調(diào)用createAopProxy()生成的對(duì)象調(diào)用getProxy()方法生成代理對(duì)象
public <T> T getProxy() {
return (T) createAopProxy().getProxy();
}
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
//這里會(huì)監(jiān)聽(tīng)調(diào)用AdvisedSupportListener實(shí)現(xiàn)類的activated方法
activate();
}
//獲取AopProxyFactory
//調(diào)用createAopProxy的時(shí)候傳入了this對(duì)象
return getAopProxyFactory().createAopProxy(this);
}
//在SpringAOP中 AopProxyFactory只有一個(gè)實(shí)現(xiàn)類揩页,這個(gè)實(shí)現(xiàn)類就是DefaultAopProxyFactory
public AopProxyFactory getAopProxyFactory() {
return this.aopProxyFactory;
}
private void activate() {
this.active = true;
for (AdvisedSupportListener listener : this.listeners) {
listener.activated(this);
}
}
b猖败、我們接著看:createAopProxy()方法:
ublic AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//這段代碼用來(lái)判斷選擇哪種創(chuàng)建代理對(duì)象的方式
//config.isOptimize() 是否對(duì)代理類的生成使用策略優(yōu)化 其作用是和isProxyTargetClass是一樣的 默認(rèn)為false
//config.isProxyTargetClass() 是否使用Cglib的方式創(chuàng)建代理對(duì)象 默認(rèn)為false
//hasNoUserSuppliedProxyInterfaces目標(biāo)類是否有接口存在 且只有一個(gè)接口的時(shí)候接口類型不是SpringProxy類型
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
//從AdvisedSupport中獲取目標(biāo)類 類對(duì)象
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.");
}
//判斷目標(biāo)類是否是接口 如果目標(biāo)類是接口的話速缆,則還是使用JDK的方式生成代理對(duì)象
//如果目標(biāo)類是Proxy類型 則還是使用JDK的方式生成代理對(duì)象
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
//使用JDK的提供的代理方式生成代理對(duì)象
return new JdkDynamicAopProxy(config);
}
}
c、我們接著往下看看createAopProxy().getProxy()方法:
public <T> T getProxy(ClassLoader classLoader) {
return (T) createAopProxy().getProxy(classLoader);
}
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
//獲取AdvisedSupport類型對(duì)象的所有接口
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
//接口是否定義了 equals和hashcode方法 正常是沒(méi)有的恩闻,定義了生成的代理以定義的為準(zhǔn)
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
//創(chuàng)建代理
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
private void findDefinedEqualsAndHashCodeMethods(Class<?>[] proxiedInterfaces) {
for (Class<?> proxiedInterface : proxiedInterfaces) {
Method[] methods = proxiedInterface.getDeclaredMethods();
for (Method method : methods) {
if (AopUtils.isEqualsMethod(method)) {
this.equalsDefined = true;
}
if (AopUtils.isHashCodeMethod(method)) {
this.hashCodeDefined = true;
}
if (this.equalsDefined && this.hashCodeDefined) {
return;
}
}
}
}
e艺糜、我們知道創(chuàng)建代理需要額外功能類繼承InvocationHandler實(shí)現(xiàn)invoke方法添加額外功能,那么我們來(lái)看看JdkDynamicAopProxy中的invoke的實(shí)現(xiàn):
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation;
Object oldProxy = null;
boolean setProxyContext = false;
//目標(biāo)對(duì)象
TargetSource targetSource = this.advised.targetSource;
Class<?> targetClass = null;
Object target = null;
try {
//接口中沒(méi)有定義 equals方法,并且調(diào)用的方法是equals方法(即Object中定義的equals方法)
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
//調(diào)用 JdkDynamicAopProxy 中寫(xiě)的equals方法
return equals(args[0]);
}else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
//和上面的分析一樣
return hashCode();
}else if (method.getDeclaringClass() == DecoratingProxy.class) {
return AopProxyUtils.ultimateTargetClass(this.advised);
}else if (!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) {
//如果 方法所在的類是接口 并且是Advised的子類,則直接調(diào)用下面的方法
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
//是否對(duì)外暴露代理對(duì)象
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
//把創(chuàng)建的代理對(duì)象放到線程上下文中返回之前老的代理
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
//從TargetSource中獲取目標(biāo)對(duì)象
target = targetSource.getTarget();
if (target != null) {
targetClass = target.getClass();
}
//從Advised中根據(jù)方法名和目標(biāo)類獲取 AOP攔截器執(zhí)行鏈 重點(diǎn)要分析的內(nèi)容
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
//如果這個(gè)執(zhí)行鏈為空的話
if (chain.isEmpty()) {
//直接進(jìn)行方法調(diào)用
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
//如果AOP攔截器執(zhí)行鏈不為空 說(shuō)明有AOP通知存在
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
//開(kāi)始調(diào)用
retVal = invocation.proceed();
}
//方法的返回值類型
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
//return this
retVal = proxy;
}
//返回值類型錯(cuò)誤
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 {
//如果目標(biāo)對(duì)象不為空 且目標(biāo)對(duì)象是可變的 如prototype類型
//通常我們的目標(biāo)對(duì)象都是單例的 即targetSource.isStatic為true
if (target != null && !targetSource.isStatic()) {
//釋放目標(biāo)對(duì)象
targetSource.releaseTarget(target);
}
if (setProxyContext) {
//線程上下文復(fù)位
AopContext.setCurrentProxy(oldProxy);
}
}
}
從上面代碼不難看出這段代碼的重點(diǎn):從Advised中根據(jù)方法名和目標(biāo)類獲取 AOP攔截器執(zhí)行鏈(List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);)那么我們來(lái)看看獲取的代碼:
f倦踢、this.advised.getInterceptorsAndDynamicInterceptionAdvice:
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
//創(chuàng)建一個(gè)method的緩存對(duì)象在MethodCacheKey中實(shí)現(xiàn)了equals和hashcode方法同時(shí)還實(shí)現(xiàn)了compareTo方法
MethodCacheKey cacheKey = new MethodCacheKey(method);
List<Object> cached = this.methodCache.get(cacheKey);
//先從緩存中獲取 如果緩存中獲取不到則再調(diào)用方法獲取,獲取之后放入到緩存中
if (cached == null) {
//調(diào)用的是advisorChainFactory的getInterceptorsAndDynamicInterceptionAdvice方法
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
this.methodCache.put(cacheKey, cached);
}
return cached;
}
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, Class<?> targetClass) {
//創(chuàng)建一個(gè)初始大小為之前獲取到的 通知個(gè)數(shù)的 集合
List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
//如果目標(biāo)類為null的話送滞,則從方法簽名中獲取目標(biāo)類
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
//判斷目標(biāo)類是否存在引介增強(qiáng)通常為false
boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
//這里用了一個(gè)單例模式獲取DefaultAdvisorAdapterRegistry實(shí)例
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
//循環(huán)目標(biāo)方法匹配的通知
for (Advisor advisor : config.getAdvisors()) {
//如果是PointcutAdvisor類型的實(shí)例 我們大多數(shù)的Advisor都是PointcutAdvisor類型的
if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
//如果提前進(jìn)行過(guò) 切點(diǎn)的匹配了或者當(dāng)前的Advisor適用于目標(biāo)類
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
//將Advisor適配為MethodInterceptor
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
//檢測(cè)Advisor是否適用于此目標(biāo)方法
if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
//MethodMatcher中的切點(diǎn)分為兩種 一個(gè)是靜態(tài)的 一種是動(dòng)態(tài)的
//如果isRuntime返回true 則是動(dòng)態(tài)的切入點(diǎn)每次方法的調(diào)用都要去進(jìn)行匹配
//而靜態(tài)切入點(diǎn)則回緩存之前的匹配結(jié)果值
if (mm.isRuntime()) {
//動(dòng)態(tài)切入點(diǎn) 則會(huì)創(chuàng)建一個(gè)InterceptorAndDynamicMethodMatcher對(duì)象
//這個(gè)對(duì)象包含MethodInterceptor和MethodMatcher 的實(shí)例
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
//添加到列表中
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
//如果是引介增強(qiáng)
else if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
//將Advisor轉(zhuǎn)換為Interceptor
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
//以上兩種都不是
else {
//將Advisor轉(zhuǎn)換為Interceptor
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
return interceptorList;
}
從上面代碼可以總結(jié)下流程:
1、循環(huán)目標(biāo)方法的所有Advisor
2辱挥、判斷Advisor的類型
? a犁嗅、如果是PointcutAdvisor的類型,則判斷此Advisor是否適用于此目標(biāo)方法
?b晤碘、如果是IntroductionAdvisor引介增強(qiáng)類型褂微,則判斷此Advisor是否適用于此目標(biāo)方法
?c、如果以上都不是园爷,則直接轉(zhuǎn)換為Interceptor類型宠蚂。
不管是Advisor哪一類型最終都會(huì)registry.getInterceptors(advisor);進(jìn)行轉(zhuǎn)換,那么我們來(lái)看看這個(gè)方法:
g童社、registry.getInterceptors(advisor):
我們來(lái)先看看registry的獲取代碼:
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
=========
public abstract class GlobalAdvisorAdapterRegistry {
private static AdvisorAdapterRegistry instance = new DefaultAdvisorAdapterRegistry();
public static AdvisorAdapterRegistry getInstance() {
return instance;
}
=========
public DefaultAdvisorAdapterRegistry() {
//前置通知適配器
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
//后置返回通知適配器
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
//后置異常通知適配器
registerAdvisorAdapter(new ThrowsAdviceAdapter());
}
接著我們來(lái)看看:registry.getInterceptors的代碼:
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
//從Advisor中獲取 Advice
Advice advice = advisor.getAdvice();
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
for (AdvisorAdapter adapter : this.adapters) {
if (adapter.supportsAdvice(advice)) {
//轉(zhuǎn)換為對(duì)應(yīng)的 MethodInterceptor類型
//AfterReturningAdviceInterceptor MethodBeforeAdviceInterceptor ThrowsAdviceInterceptor
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[interceptors.size()]);
}
l求厕、攔截器連的調(diào)用過(guò)程:
invoke方法中的:
//如果AOP攔截器執(zhí)行鏈不為空 說(shuō)明有AOP通知存在
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
//開(kāi)始調(diào)用
retVal = invocation.proceed();
那么我們來(lái)看看這個(gè)方法:
public Object proceed() throws Throwable {
// 如果執(zhí)行到鏈條的末尾則直接調(diào)用連接點(diǎn)方法即直接調(diào)用目標(biāo)方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
//調(diào)用目標(biāo)方法
return invokeJoinpoint();
}
//獲取集合中的 MethodInterceptor
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
//如果是InterceptorAndDynamicMethodMatcher類型
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
//這里每一次都去匹配是否適用于這個(gè)目標(biāo)方法
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
//如果匹配則直接調(diào)用 MethodInterceptor的invoke方法
return dm.interceptor.invoke(this);
}
else {
//如果不適用于此目標(biāo)方法 則繼續(xù)執(zhí)行下一個(gè)鏈條 遞歸調(diào)用
return proceed();
}
}
else {
//直接調(diào)用 MethodInterceptor的invoke方法
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
看下invokeJoinpoint方法(直接掉用目標(biāo)類的方法):
protected Object invokeJoinpoint() throws Throwable {
//this.target 目標(biāo)對(duì)象
//this.method 目標(biāo)方法
this.arguments 目標(biāo)方法參數(shù)信息
return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
}
public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args)
throws Throwable {
// Use reflection to invoke the method.
try {
//設(shè)置方法可見(jiàn)性
ReflectionUtils.makeAccessible(method);
//反射調(diào)用 最終是通過(guò)反射去調(diào)用目標(biāo)方法
return method.invoke(target, args);
}
catch (InvocationTargetException ex) {
// Invoked method threw a checked exception.
// We must rethrow it. The client won't see the interceptor.
throw ex.getTargetException();
}
catch (IllegalArgumentException ex) {
throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" +
method + "] on target [" + target + "]", ex);
}
catch (IllegalAccessException ex) {
throw new AopInvocationException("Could not access method [" + method + "]", ex);
}
}