DATAREST-684 - ProxyProjectionFactory now exposes target instance on proxy.
Changed TargetClassAware to TargetAware and expose the actual proxy target for framework purposes.
This commit is contained in:
@@ -29,8 +29,6 @@ import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
/**
|
||||
* A {@link ProjectionFactory} to create JDK proxies to back interfaces and handle method invocations on them. By
|
||||
* default accessor methods are supported. In case the delegating lookups result in an object of different type that the
|
||||
@@ -64,13 +62,13 @@ class ProxyProjectionFactory implements ProjectionFactory {
|
||||
ProxyFactory factory = new ProxyFactory();
|
||||
factory.setTarget(source);
|
||||
factory.setOpaque(true);
|
||||
factory.setInterfaces(projectionType, TargetClassAware.class);
|
||||
factory.setInterfaces(projectionType, TargetAware.class);
|
||||
|
||||
if (IS_JAVA_8) {
|
||||
factory.addAdvice(new DefaultMethodInvokingMethodInterceptor());
|
||||
}
|
||||
|
||||
factory.addAdvice(new TargetClassAwareMethodInterceptor(source.getClass()));
|
||||
factory.addAdvice(new TargetAwareMethodInterceptor(source.getClass()));
|
||||
factory.addAdvice(getMethodInterceptor(source, projectionType));
|
||||
|
||||
return (T) factory.getProxy(getClass().getClassLoader());
|
||||
@@ -152,45 +150,37 @@ class ProxyProjectionFactory implements ProjectionFactory {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extension of {@link org.springframework.aop.TargetClassAware} to be able to ignore the getter on JSON rendering.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public static interface TargetClassAware extends org.springframework.aop.TargetClassAware {
|
||||
|
||||
@JsonIgnore
|
||||
Class<?> getTargetClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom {@link MethodInterceptor} to expose the proxy target class even if we set
|
||||
* {@link ProxyFactory#setOpaque(boolean)} to true to prevent properties on {@link Advised} to be rendered.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private static class TargetClassAwareMethodInterceptor implements MethodInterceptor {
|
||||
private static class TargetAwareMethodInterceptor implements MethodInterceptor {
|
||||
|
||||
private static final Method GET_TARGET_CLASS_METHOD;
|
||||
private final Class<?> targetClass;
|
||||
private static final Method GET_TARGET_METHOD;
|
||||
|
||||
private final Class<?> targetType;
|
||||
|
||||
static {
|
||||
try {
|
||||
GET_TARGET_CLASS_METHOD = TargetClassAware.class.getMethod("getTargetClass");
|
||||
GET_TARGET_CLASS_METHOD = TargetAware.class.getMethod("getTargetClass");
|
||||
GET_TARGET_METHOD = TargetAware.class.getMethod("getTarget");
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link TargetClassAwareMethodInterceptor} with the given target class.
|
||||
* Creates a new {@link TargetAwareMethodInterceptor} with the given target class.
|
||||
*
|
||||
* @param targetClass must not be {@literal null}.
|
||||
* @param targetType must not be {@literal null}.
|
||||
*/
|
||||
public TargetClassAwareMethodInterceptor(Class<?> targetClass) {
|
||||
public TargetAwareMethodInterceptor(Class<?> targetType) {
|
||||
|
||||
Assert.notNull(targetClass, "Target class must not be null!");
|
||||
this.targetClass = targetClass;
|
||||
Assert.notNull(targetType, "Target type must not be null!");
|
||||
this.targetType = targetType;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -201,7 +191,9 @@ class ProxyProjectionFactory implements ProjectionFactory {
|
||||
public Object invoke(MethodInvocation invocation) throws Throwable {
|
||||
|
||||
if (invocation.getMethod().equals(GET_TARGET_CLASS_METHOD)) {
|
||||
return targetClass;
|
||||
return targetType;
|
||||
} else if (invocation.getMethod().equals(GET_TARGET_METHOD)) {
|
||||
return invocation.getThis();
|
||||
}
|
||||
|
||||
return invocation.proceed();
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2015 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.data.projection;
|
||||
|
||||
import org.springframework.aop.RawTargetAccess;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
/**
|
||||
* Extension of {@link org.springframework.aop.TargetClassAware} to be able to ignore the getter on JSON rendering.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface TargetAware extends org.springframework.aop.TargetClassAware, RawTargetAccess {
|
||||
|
||||
/**
|
||||
* Returns the type of the proxy target.
|
||||
*
|
||||
* @return will never be {@literal null}.
|
||||
*/
|
||||
@JsonIgnore
|
||||
Class<?> getTargetClass();
|
||||
|
||||
/**
|
||||
* Returns the proxy target.
|
||||
*
|
||||
* @return will never be {@literal null}.
|
||||
*/
|
||||
@JsonIgnore
|
||||
Object getTarget();
|
||||
}
|
||||
Reference in New Issue
Block a user