您的位置:首页 > 编程语言 > Java开发

spring aop 的主要流程和设计模式

2019-04-29 20:05 651 查看

spring初始化的时候

调用后置处理器 获取对象方法的通知(增强器)

@Override
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, @Nullable Class<?> targetClass) {
// This is somewhat tricky... We have to process introductions first,
// but we need to preserve order in the ultimate list.
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;
......

利用代理工厂创建代理对象(根据是否实现接口,选择jdk和cglib)
以上是容器初始化的时候做的

然后业务里调用代理对象方法

spring从代理工厂获取拦截器链(获取增强器转成instecpet拦截器,适配器模式)

.......
else if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
else {
Interceptor[] interceptors = registry.getInterceptors(advisor);//转换成拦截器
interceptorList.addAll(Arrays.asList(interceptors));//加入拦截器链
}
}

return interceptorList;
}

然后递归执行

@Override
@Nullable
public Object proceed() throws Throwable {
//	We start with an index of -1 and increment early.
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();//如果遍历到拦截器最后一个,则调用反射执行目标方法
}
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;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
if (dm.methodMatcher.matches(this.method, 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);//递归遍历
}
}

invoke方法按照拦截器的类型多态调用
把ExposeInvocationInterceptor
异常通知AspectJAfterThrowingAdvice
返回通知AfterReturningAdviceInterceptor
后置通知AspectJAfterAdvice
前置通知MethodBeforeAdviceInterceptor依次压入栈中,

在MethodBeforeAdviceInterceptor中先执行前置通知方法,然后返回执行目标方法(退出递归条件已经满足),然后依次返回执行后置通知,返回通知,异常通知(责任链模式)

@Override
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
return mi.proceed();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: