Java Code Examples for org.springframework.aop.support.AopUtils#isHashCodeMethod()

The following examples show how to use org.springframework.aop.support.AopUtils#isHashCodeMethod() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: JdkDynamicAopProxy.java    From spring-analysis-note with MIT License 6 votes vote down vote up
/**
 * Finds any {@link #equals} or {@link #hashCode} method that may be defined
 * on the supplied set of interfaces.
 * @param proxiedInterfaces the interfaces to introspect
 */
private void findDefinedEqualsAndHashCodeMethods(Class<?>[] proxiedInterfaces) {
	for (Class<?> proxiedInterface : proxiedInterfaces) {
		Method[] methods = proxiedInterface.getDeclaredMethods();
		for (Method method : methods) {
			if (AopUtils.isEqualsMethod(method)) {
				this.equalsDefined = true;
			}
			if (AopUtils.isHashCodeMethod(method)) {
				this.hashCodeDefined = true;
			}
			if (this.equalsDefined && this.hashCodeDefined) {
				return;
			}
		}
	}
}
 
Example 2
Source File: JdkDynamicAopProxy.java    From java-technology-stack with MIT License 6 votes vote down vote up
/**
 * Finds any {@link #equals} or {@link #hashCode} method that may be defined
 * on the supplied set of interfaces.
 * @param proxiedInterfaces the interfaces to introspect
 */
private void findDefinedEqualsAndHashCodeMethods(Class<?>[] proxiedInterfaces) {
	for (Class<?> proxiedInterface : proxiedInterfaces) {
		Method[] methods = proxiedInterface.getDeclaredMethods();
		for (Method method : methods) {
			if (AopUtils.isEqualsMethod(method)) {
				this.equalsDefined = true;
			}
			if (AopUtils.isHashCodeMethod(method)) {
				this.hashCodeDefined = true;
			}
			if (this.equalsDefined && this.hashCodeDefined) {
				return;
			}
		}
	}
}
 
Example 3
Source File: EagleTraceJdkProxy.java    From eagle with Apache License 2.0 6 votes vote down vote up
private void findDefinedEqualsAndHashCodeMethods(Class<?>[] proxiedInterfaces) {
    for (Class<?> proxiedInterface : proxiedInterfaces) {
        Method[] methods = proxiedInterface.getDeclaredMethods();
        for (Method method : methods) {
            if (AopUtils.isEqualsMethod(method)) {
                this.equalsDefined = true;
            }
            if (AopUtils.isHashCodeMethod(method)) {
                this.hashCodeDefined = true;
            }
            if (this.equalsDefined && this.hashCodeDefined) {
                return;
            }
        }
    }
}
 
Example 4
Source File: JdkDynamicAopProxy.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Finds any {@link #equals} or {@link #hashCode} method that may be defined
 * on the supplied set of interfaces.
 * @param proxiedInterfaces the interfaces to introspect
 */
private void findDefinedEqualsAndHashCodeMethods(Class<?>[] proxiedInterfaces) {
	for (Class<?> proxiedInterface : proxiedInterfaces) {
		Method[] methods = proxiedInterface.getDeclaredMethods();
		for (Method method : methods) {
			if (AopUtils.isEqualsMethod(method)) {
				this.equalsDefined = true;
			}
			if (AopUtils.isHashCodeMethod(method)) {
				this.hashCodeDefined = true;
			}
			if (this.equalsDefined && this.hashCodeDefined) {
				return;
			}
		}
	}
}
 
Example 5
Source File: JdkDynamicAopProxy.java    From spring4-understanding with Apache License 2.0 6 votes vote down vote up
/**
 * Finds any {@link #equals} or {@link #hashCode} method that may be defined
 * on the supplied set of interfaces.
 * @param proxiedInterfaces the interfaces to introspect
 */
private void findDefinedEqualsAndHashCodeMethods(Class<?>[] proxiedInterfaces) {
	for (Class<?> proxiedInterface : proxiedInterfaces) {
		Method[] methods = proxiedInterface.getDeclaredMethods();
		for (Method method : methods) {
			if (AopUtils.isEqualsMethod(method)) {
				this.equalsDefined = true;
			}
			if (AopUtils.isHashCodeMethod(method)) {
				this.hashCodeDefined = true;
			}
			if (this.equalsDefined && this.hashCodeDefined) {
				return;
			}
		}
	}
}
 
Example 6
Source File: CglibAopProxy.java    From spring-analysis-note with MIT License 5 votes vote down vote up
public CglibMethodInvocation(Object proxy, @Nullable Object target, Method method,
		Object[] arguments, @Nullable Class<?> targetClass,
		List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {

	super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);

	// Only use method proxy for public methods not derived from java.lang.Object
	this.methodProxy = (Modifier.isPublic(method.getModifiers()) &&
			method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) &&
			!AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method) ?
			methodProxy : null);
}
 
Example 7
Source File: CglibAopProxy.java    From java-technology-stack with MIT License 5 votes vote down vote up
public CglibMethodInvocation(Object proxy, @Nullable Object target, Method method,
		Object[] arguments, @Nullable Class<?> targetClass,
		List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {

	super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);

	// Only use method proxy for public methods not derived from java.lang.Object
	this.methodProxy = (Modifier.isPublic(method.getModifiers()) &&
			method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) &&
			!AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method) ?
			methodProxy : null);
}
 
Example 8
Source File: JdkDynamicAopProxy.java    From spring-analysis-note with MIT License 4 votes vote down vote up
/**
 * Implementation of {@code InvocationHandler.invoke}.
 * <p>Callers will see exactly the exception thrown by the target,
 * unless a hook method throws an exception.
 */
@Override
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
	// 注释 8.12 jdk 动态代理重载的 invoke 方法
	MethodInvocation invocation;
	Object oldProxy = null;
	boolean setProxyContext = false;

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

	try {
		// 处理 equals 方法
		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);

		// Check whether we have any advice. If we don't, we can fallback on direct
		// reflective invocation of the target, and avoid creating a MethodInvocation.
		// 检查我们是否有任何切面逻辑。如果我们不这样做,我们可以回退直接反射调用目标,并避免创建 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...
			// 将拦截器封装在 ReflectiveMethodInvocation,便于使用 proceed 执行拦截器
			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);
		}
	}
}
 
Example 9
Source File: JdkDynamicAopProxy.java    From java-technology-stack with MIT License 4 votes vote down vote up
/**
 * Implementation of {@code InvocationHandler.invoke}.
 * <p>Callers will see exactly the exception thrown by the target,
 * unless a hook method throws an exception.
 */
@Override
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
	MethodInvocation invocation;
	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);

		// Check whether we have any advice. If we don't, we can fallback on direct
		// reflective invocation of the target, and avoid creating a 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...
			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);
		}
	}
}
 
Example 10
Source File: EagleTraceCglibProxy.java    From eagle with Apache License 2.0 4 votes vote down vote up
@Override
public int accept(Method method) {
    if (AopUtils.isFinalizeMethod(method)) {
        logger.debug("Found finalize() method - using NO_OVERRIDE");
        return NO_OVERRIDE;
    }
    if (!this.advised.isOpaque() && method.getDeclaringClass().isInterface() &&
            method.getDeclaringClass().isAssignableFrom(Advised.class)) {
        if (logger.isDebugEnabled()) {
            logger.debug("Method is declared on Advised interface: " + method);
        }
        return DISPATCH_ADVISED;
    }
    // We must always proxy equals, to direct calls to this.
    if (AopUtils.isEqualsMethod(method)) {
        logger.debug("Found 'equals' method: " + method);
        return INVOKE_EQUALS;
    }
    // We must always calculate hashCode based on the proxy.
    if (AopUtils.isHashCodeMethod(method)) {
        logger.debug("Found 'hashCode' method: " + method);
        return INVOKE_HASHCODE;
    }
    Class<?> targetClass = this.advised.getTargetClass();
    // Proxy is not yet available, but that shouldn't matter.
    List<?> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
    boolean haveAdvice = !chain.isEmpty();
    boolean exposeProxy = this.advised.isExposeProxy();
    boolean isStatic = this.advised.getTargetSource().isStatic();
    boolean isFrozen = this.advised.isFrozen();
    if (haveAdvice || !isFrozen) {
        // If exposing the proxy, then AOP_PROXY must be used.
        if (exposeProxy) {
            if (logger.isDebugEnabled()) {
                logger.debug("Must expose proxy on advised method: " + method);
            }
            return AOP_PROXY;
        }
        String key = method.toString();
        // Check to see if we have fixed interceptor to serve this method.
        // Else use the AOP_PROXY.
        if (isStatic && isFrozen && this.fixedInterceptorMap.containsKey(key)) {
            if (logger.isDebugEnabled()) {
                logger.debug("Method has advice and optimisations are enabled: " + method);
            }
            // We know that we are optimising so we can use the
            // FixedStaticChainInterceptors.
            int index = this.fixedInterceptorMap.get(key);
            return (index + this.fixedInterceptorOffset);
        } else {
            if (logger.isDebugEnabled()) {
                logger.debug("Unable to apply any optimisations to advised method: " + method);
            }
            return AOP_PROXY;
        }
    } else {
        // See if the return type of the method is outside the class hierarchy
        // of the target type. If so we know it never needs to have return type
        // massage and can use a dispatcher.
        // If the proxy is being exposed, then must use the interceptor the
        // correct one is already configured. If the target is not static, then
        // cannot use a dispatcher because the target cannot be released.
        if (exposeProxy || !isStatic) {
            return INVOKE_TARGET;
        }
        Class<?> returnType = method.getReturnType();
        if (targetClass == returnType) {
            if (logger.isDebugEnabled()) {
                logger.debug("Method " + method +
                        "has return type same as target type (may return this) - using INVOKE_TARGET");
            }
            return INVOKE_TARGET;
        } else if (returnType.isPrimitive() || !returnType.isAssignableFrom(targetClass)) {
            if (logger.isDebugEnabled()) {
                logger.debug("Method " + method +
                        " has return type that ensures this cannot be returned- using DISPATCH_TARGET");
            }
            return DISPATCH_TARGET;
        } else {
            if (logger.isDebugEnabled()) {
                logger.debug("Method " + method +
                        "has return type that is assignable from the target type (may return this) - " +
                        "using INVOKE_TARGET");
            }
            return INVOKE_TARGET;
        }
    }
}
 
Example 11
Source File: EagleTraceJdkProxy.java    From eagle with Apache License 2.0 4 votes vote down vote up
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    TargetSource targetSource = this.advised.getTargetSource();
    Class<?> targetClass = null;
    Object target = null;

    try {
        if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
            // The target does not implement the equals(Object) method itself.
            return equals(args[0]);
        }
        if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
            // The target does not implement the hashCode() method itself.
            return hashCode();
        }
        if (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;

        // May be null. Get as late as possible to minimize the time we "own" the target,
        // in case it comes from a pool.
        target = targetSource.getTarget();
        if (target != null) {
            targetClass = target.getClass();
        }

        if (EagleTraceMethodRecods.needTrace(method, targetClass)) {
            boolean clear = Strings.isNullOrEmpty(TraceContext.getTraceId());
            try {
                if (clear) {
                    TraceContext.setTraceId(OpaqueGenerator.getDistributeOpaque());
                }
                retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
            } catch (Throwable e) {
                logger.error("Eagle trace error:  ", e);
                throw new EagleFrameException(e);
            } finally {
                if (clear) {
                    TraceContext.clear();
                }
            }

        } else {
            retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
        }

        // Massage return value if necessary.
        Class<?> returnType = method.getReturnType();
        if (retVal != null && retVal == target && returnType.isInstance(proxy) &&
                !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
            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);
        }
    }
}
 
Example 12
Source File: JdkDynamicAopProxy.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Implementation of {@code InvocationHandler.invoke}.
 * <p>Callers will see exactly the exception thrown by the target,
 * unless a hook method throws an exception.
 */
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
	MethodInvocation invocation;
	Object oldProxy = null;
	boolean setProxyContext = false;

	TargetSource targetSource = this.advised.targetSource;
	Class<?> targetClass = null;
	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;
		}

		// May be null. Get as late as possible to minimize the time we "own" the target,
		// in case it comes from a pool.
		target = targetSource.getTarget();
		if (target != null) {
			targetClass = target.getClass();
		}

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

		// Check whether we have any advice. If we don't, we can fallback on direct
		// reflective invocation of the target, and avoid creating a 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...
			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);
		}
	}
}
 
Example 13
Source File: JdkDynamicAopProxy.java    From spring4-understanding with Apache License 2.0 4 votes vote down vote up
/**
 * Implementation of {@code InvocationHandler.invoke}.
 * <p>Callers will see exactly the exception thrown by the target,
 * unless a hook method throws an exception.
 */
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
	MethodInvocation invocation;
	Object oldProxy = null;
	boolean setProxyContext = false;

	TargetSource targetSource = this.advised.targetSource;
	Class<?> targetClass = null;
	Object target = null;

	try {
		if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
			// The target does not implement the equals(Object) method itself.
			return equals(args[0]);
		}
		if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
			// The target does not implement the hashCode() method itself.
			return hashCode();
		}
		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;
		}

		// May be null. Get as late as possible to minimize the time we "own" the target,
		// in case it comes from a pool.
		target = targetSource.getTarget();
		if (target != null) {
			targetClass = target.getClass();
		}

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

		// Check whether we have any advice. If we don't, we can fallback on direct
		// reflective invocation of the target, and avoid creating a 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...
			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.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);
		}
	}
}