AOP有标准化的定义.
通俗解释AOP:面向所关心方面的编程.(比如,在系统中如果需要对每个操作做RoleCheck,则可以建一个类RoleCheck,来管理这个方面)
Spring AOP是实现AOP的一种方式.
AOP的几个概念:
1 Advice:
即你在关注点所想做的一些动作,如你需要RoleCheck时进行的操作.( org.aopalliance.intercept.Advice)
分类:
MethodInterceptor (org.aopalliance.intercept.MethodInterceptor)
Advice org.aopalliance.aop.Advice
---BeforeAdvice extends Advice org.springframework.aop.BeforeAdvice 在目标方法被调用之前调用
public Object invoke(MethodInvocation mi) throws Throwable {
//先调用before方法,这是实现BeforeAdvice接口的类, 然后再调用余下的advice
// before方法内容 即自定义在目标方法被调用之前要做动作
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
return mi.proceed();
}
---AfterAdvice extends Advice org.springframework.aop.AfterReturningAdvice 在目标方法被调用之后调用
public Object invoke(MethodInvocation mi) throws Throwable {
//先调用在这个advice之前的advice, 后调用afterReturning方法,这是实现AfterAdvice接口的类,
// afterReturning() 函数内容即自定义在目标方法被调用之后要做的动作
Object retVal = mi.proceed();
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}
---ThrowsAdvice extends Advice org.springframework.aop.ThrowsAdvice 在目标方法抛出异常时调用
2. PointCut
指的是需要关注的点.即需要增加所定义的advice的点.如你需要在调用viewlist()前进行RoleCheck,那这个viewlist()就是一个pointcut
3.Advisor
由定义切面的advice和定义切面在什么地方执行的pointcut而成的就是Advisor。
4.生成AopProxy
.....待
5.Spring AOP Interceptor 调用的过程.(jdk动态代理方式实现)
1当目标函数被调用时,由于jdk的动态代理. 进入JdkDynamicAopProxy.invoke(){
(1). 得到targetSource,即被关注的函数
(2). 得到 intercetion chain,即定义的advice
(3).判断chain,如果为空,直接invokeJoinpoint,否则生成invocation,然后invoke这些advice.
if (chain.isEmpty()) { // We can skip creating a MethodInvocation: just invoke the target directly // Note that the final invoker must be an InvokerInterceptor so we know it does // nothing but a reflective operation on the target, and no hot swapping or fancy proxying. retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args); } else { // We need to create a method invocation... invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); // Proceed to the joinpoint through the interceptor chain. retVal = invocation.proceed(); }
2. 进入 ReflectiveMethodInvocation.proceed(), 然后会一次进入beforeAdvice或afterAdvice,递归调用其中的proceed,
public Object proceed() throws Throwable { // We start with an index of -1 and increment early. // 判断 interception chain 中的advice是否已经访问完 if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { // 如果已经访问完,则invoke joinPoint,即调用目标对象 return invokeJoinpoint(); } // 得到当前advice的引用 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; 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 { // It's an interceptor, so we just invoke it: The pointcut will have // been evaluated statically before this object was constructed. // invoke 当前的advice return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } }
3.当递归进入到proceed(),发现所有interception chain中的advice已经处理完,调用 invokeJoinPoint(),
protected Object invokeJoinpoint() throws Throwable { return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments); }
4. 完成后, 递归返回.