Primavera 5.x trip Fuente consulta cuarenta y nueve AOP notificación método de orden de ejecución

Cómo ejecución del método de notificación AOP

Mira toda la AOPestructura interna de la orden de ejecución de los métodos básicos de la notificación:
Aquí Insertar imagen Descripción
Tomamos un JDKproxy dinámico, por ejemplo, CGLIBes similar, cuando se llama a un método, será JdkDynamicAopProxyel agente de invokeejecución:

@Override
	@Nullable
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Object oldProxy = null;
		boolean setProxyContext = false;

		TargetSource targetSource = this.advised.targetSource;
		Object target = null;

		try {
			if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
				// The target does not implement the equals(Object) method itself.
				return equals(args[0]);
			}
			else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
				// The target does not implement the hashCode() method itself.
				return hashCode();
			}
			else if (method.getDeclaringClass() == DecoratingProxy.class) {
				// There is only getDecoratedClass() declared -> dispatch to proxy config.
				return AopProxyUtils.ultimateTargetClass(this.advised);
			}
			else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
					method.getDeclaringClass().isAssignableFrom(Advised.class)) {
				// Service invocations on ProxyConfig with the proxy config...
				return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
			}

			Object retVal;

			if (this.advised.exposeProxy) {
				// Make invocation available if necessary.
				oldProxy = AopContext.setCurrentProxy(proxy);
				setProxyContext = true;
			}

			// Get as late as possible to minimize the time we "own" the target,
			// in case it comes from a pool.
			target = targetSource.getTarget();
			Class<?> targetClass = (target != null ? target.getClass() : null);

			// Get the interception chain for this method.
			List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

			
			MethodInvocation.
			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.
				Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
				retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
			}
			else {
				// We need to create a method invocation...
				MethodInvocation invocation =
						new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
				// Proceed to the joinpoint through the interceptor chain.
				retVal = invocation.proceed();
			}

			// Massage return value if necessary.
			Class<?> returnType = method.getReturnType();
			if (retVal != null && retVal == target &&
					returnType != Object.class && returnType.isInstance(proxy) &&
					!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
				// Special case: it returned "this" and the return type of the method
				// is type-compatible. Note that we can't help if the target sets
				// a reference to itself in another returned object.
				retVal = proxy;
			}
			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 {
			if (target != null && !targetSource.isStatic()) {
				// Must have come from TargetSource.
				targetSource.releaseTarget(target);
			}
			if (setProxyContext) {
				// Restore old proxy.
				AopContext.setCurrentProxy(oldProxy);
			}
		}
	}

Montón, de hecho, tan pocos importante, en primer lugar obtener todas las notificaciones List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);y luego se envasa en una ReflectiveMethodInvocationllamada de proceedmétodo. Pongo el enfoque general de AOP tiene que pasar, se puede ver en la que ya está terminado pidiendo, específicamente la forma de una especie, se puede ir a estudiar, más complicado, de hecho, con el fin de formar un orden pila de llamadas, atraeré a la parte trasera, nos fijamos en el uso de estos, de hecho, nada específico con la primera, que dirigirá la aplicación de la segunda y, a continuación, pasar a realizar en este orden:
Aquí Insertar imagen Descripción

ReflectiveMethodInvocation de ciclos de ejecución proceder

El principal es un notificaciones Get recursivos, y luego ejecutados.

@Override
	@Nullable
	public Object proceed() throws Throwable {
		// 循环执行,直到执行完
		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);
		}
	}

ExposeInvocationInterceptor 的 invoke

Yo no lo hice, sobre todo mi.proceed(), es decir, seguir llamando ReflectiveMethodInvocation的proceedpara hacer llamadas recursivas.

@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		MethodInvocation oldInvocation = invocation.get();
		invocation.set(mi);
		try {
			return mi.proceed();
		}
		finally {
			invocation.set(oldInvocation);
		}
	}

AspectJAfterThrowingAdvice invocar la excepción de notificación

De hecho, la capa externa de la captura de pan excepción, y luego continuar a la llamada mi.proceed();, si una anomalía que puede ser capturado a realizar invokeAdviceMethod.

	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		try {
			return mi.proceed();
		}
		catch (Throwable ex) {
			if (shouldInvokeOnThrowing(ex)) {
				invokeAdviceMethod(getJoinPointMatch(), null, ex);
			}
			throw ex;
		}
	}

AbstractAspectJAdvice método de notificación de invokeAdviceMethod

De hecho, este es un método común de notificación, siempre y cuando el método de notificación que se llamará, será la última llamada para llamar a esta dentro de este:
Aquí Insertar imagen Descripción

Después del regreso exitoso de AfterReturningAdviceInterceptor invocación de notificación

Justo después de volver más método es llamar el interior invokeAdviceMethod.

	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		Object retVal = mi.proceed();
		this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
		return retVal;
	}

AspectJAfterAdvice invocación de método de notificación

Es decir, después de la aplicación de la ejecución invokeAdviceMethod.

	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		try {
			return mi.proceed();
		}
		finally {
			invokeAdviceMethod(getJoinPointMatch(), null, null);
		}
	}

AspectJAroundAdvice invocar el asesoramiento en torno

Esto pondrá MethodInvocationel paquete en ProceedingJoinPointy, a continuación, pasar como parámetros cuando se invoca.

	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		if (!(mi instanceof ProxyMethodInvocation)) {
			throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
		}
		ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
		ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
		JoinPointMatch jpm = getJoinPointMatch(pmi);
		return invokeAdviceMethod(pjp, jpm, null, null);
	}

Primer paquete:
Aquí Insertar imagen Descripción
Después del uso:
Aquí Insertar imagen Descripción
Luego será clonado, tal vez la agencia para proteger los datos de origen, y luego llamar a proceed:
Aquí Insertar imagen Descripción

método de invocación MethodBeforeAdviceInterceptor antes de la notificación

Antes de llamar al método primera notificación método, una llamada al método.

	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
		return mi.proceed();
	}

El proceso básico es tan abajo, así que por qué está rodeada en la parte delantera, ya que la parte trasera rodeado por agentes del método para llevar a cabo, antes de rodear transformación llevada a cabo con antelación:
Aquí Insertar imagen Descripción
Si una excepción es decir:
Aquí Insertar imagen Descripción
vistazo a toda la estructura es la siguiente:
Aquí Insertar imagen DescripciónHM6Ly9ibG9nLmNzZG4ubmV0L3dhbmd3ZWkxOTg3MTEwMw == , size_16, color_FFFFFF, t_70)
normalmente se puede controlar, que no es inusual, cuestión nada.
Si una excepción es que aparezca en System.out.println("方法调用");tanto ejecutados directamente System.out.println("logAfter");, la ejecución no va a ir logReturningdirectamente en el catchinterior, con una excepción cuando la información también está en alza.

Pues bien, el básico de AOPanálisis llamada ha terminado, después de que el aviso es en realidad un método bueno para ordenar, llamadas recursivas. De hecho, hay otras características, tales como DeclareParents, target, argsy otras anotaciones, con este fundamento, no debería ser difícil, su propia investigación simplemente genial.

Pues bien, hoy aquí, esperamos estudio ayuda y entender, no rocíe el Gran Dios ver, comprender solamente su propio aprendizaje, capacidad limitada, por favor excusa.

Publicados 235 artículos originales · ganado elogios 74 · Vistas a 30000 +

Supongo que te gusta

Origin blog.csdn.net/wangwei19871103/article/details/105230897
Recomendado
Clasificación