⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 reflectivemethodinvocation.java

📁 spring的源代码
💻 JAVA
字号:
/*
 * Copyright 2002-2004 the original author or authors.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */ 

package org.springframework.aop.framework;

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Method;
import java.util.List;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

/**
 * Spring implementation of AOP Alliance MethodInvocation interface.
 *
 * <p>Invokes target using reflection. Subclasses can override the
 * invokeJoinpoint() method to change this behaviour, so this is a
 * useful base class for MethodInvocation implementations.
 *
 * @author Rod Johnson
 * @version $Id: ReflectiveMethodInvocation.java,v 1.5 2004/04/21 17:49:36 jhoeller Exp $
 * @see #invokeJoinpoint
 */
public class ReflectiveMethodInvocation implements MethodInvocation {

	protected Method method;
	
	protected Object[] arguments;
	
	protected Object target;
	
	protected Object proxy;
	
	/** 
	 * List of Methodnterceptor and InterceptorAndDynamicMethodMatcher
	 * that need dynamic checks.
	 */
	protected List interceptorsAndDynamicMethodMatchers;
	
	/**
	 * Index from 0 of the current interceptor we're invoking.
	 * -1 until we invoke: then the current interceptor
	 */
	private int currentInterceptorIndex = -1;
	
	private Class targetClass;
	
	
	/**
	 * Construct a new MethodInvocation with given arguments
	 * @param interceptorsAndDynamicMethodMatchers interceptors that should be applied,
	 * along with any InterceptorAndDynamicMethodMatchers that need evaluation at runtime.
	 * MethodMatchers included in this struct must already have been found to have matched as far
	 * as was possibly statically. Passing an array might be about 10% faster, but would complicate
	 * the code. And it would work only for static pointcuts.
	 */
	public ReflectiveMethodInvocation(Object proxy, Object target, 
					Method m, Object[] arguments,
					Class targetClass, List interceptorsAndDynamicMethodMatchers) {
		this.proxy = proxy;
		this.target = target;
		this.targetClass = targetClass;
		this.method = m;
		this.arguments = arguments;
		this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;
	}
	
	
	/**
	 * Return the method invoked on the proxied interface.
	 * May or may not correspond with a method invoked on an underlying
	 * implementation of that interface.
	 * @return Method
	 */
	public final Method getMethod() {
		return this.method;
	}
	
	public final AccessibleObject getStaticPart() {
		return this.method;
	}
	
	/**
	 * Return the proxy that this interception was made through
	 * @return Object
	 */
	public final Object getProxy() {
		return this.proxy;
	}
	
	/**
	 * Private optimization method
	 * @return Object[]
	 */
	public final Object[] getArguments() {
		return this.arguments;
	}
	
	/**
	 * @see org.aopalliance.intercept.Invocation#proceed
	 */
	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;
			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.
			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
		}
	}
	
	/**
	 * Invoke the joinpoint using reflection.
	 * Subclasses can override this to use custom invocation.
	 * @return the return value of the joinpoint
	 * @throws Throwable if invoking the joinpoint resulted in an exception
	 */
	protected Object invokeJoinpoint() throws Throwable {
		return AopProxyUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
	}


	/**
	 * @see org.aopalliance.intercept.Invocation#getThis
	 */
	public final Object getThis() {
		return this.target;
	}
	
	public String toString() {
		// Don't do toString on target, it may be proxied.
		// toString on args may also fail.
		StringBuffer sb = new StringBuffer("Invocation: method=[");
		sb.append(this.method).append("] ").append("args=").append(this.arguments).append("] ");
		if (this.target == null) {
			sb.append("target is null");
		}
		else {
			sb.append("target is of class [").append(this.target.getClass().getName()).append(']');
		}
		return sb.toString();
	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -