📄 reflectivemethodinvocation.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 + -