DATACMNS-661 - Improvements in SpelAwareProxyProjectionFactory.

We now allow a SpelExpressionParser to be configured on the SpelAwareProxyProjectionFactory. This parser is then passed on to SpelEvaluatingMethodInterceptor. We also now eagerly pre-parse any SpEL expression in @Value annotations on methods of the projection interface. This avoids repeated evaluations during the actual method invocations.

Original pull request: #118.
This commit is contained in:
Thomas Darimont
2015-03-18 17:41:17 +01:00
committed by Oliver Gierke
parent 537fc430a9
commit 0cf395c1b1
4 changed files with 109 additions and 23 deletions

View File

@@ -20,17 +20,25 @@ import static org.junit.Assert.*;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.expression.spel.standard.SpelExpressionParser;
/**
* Unit tests for {@link SpelAwareProxyProjectionFactory}.
*
* @author Oliver Gierke
* @author Thomas Darimont
*/
public class SpelAwareProxyProjectionFactoryUnitTests {
private final SpelAwareProxyProjectionFactory factory = new SpelAwareProxyProjectionFactory();
private SpelAwareProxyProjectionFactory factory;
@Before
public void setup() {
factory = new SpelAwareProxyProjectionFactory();
}
/**
* @see DATAREST-221, DATACMNS-630
@@ -58,6 +66,22 @@ public class SpelAwareProxyProjectionFactoryUnitTests {
assertThat(properties, hasItem("firstname"));
}
/**
* @see DATACMNS-661
*/
@Test
public void shouldSupportConfiguringFactoryWithCustomSpelParser() {
Customer customer = new Customer();
customer.firstname = "Dave";
customer.lastname = "Matthews";
factory.setParser(new SpelExpressionParser());
CustomerExcerpt excerpt = factory.createProjection(CustomerExcerpt.class, customer);
assertThat(excerpt.getFullName(), is("Dave Matthews"));
}
static class Customer {
public String firstname, lastname;

View File

@@ -30,11 +30,13 @@ import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.expression.spel.standard.SpelExpressionParser;
/**
* Unit tests for {@link SpelEvaluatingMethodInterceptor}.
*
* @author Oliver Gierke
* @author Thomas Darimont
*/
@RunWith(MockitoJUnitRunner.class)
public class SpelEvaluatingMethodInterceptorUnitTests {
@@ -42,6 +44,8 @@ public class SpelEvaluatingMethodInterceptorUnitTests {
@Mock MethodInterceptor delegate;
@Mock MethodInvocation invocation;
SpelExpressionParser parser = new SpelExpressionParser();
/**
* @see DATAREST-221, DATACMNS-630
*/
@@ -50,7 +54,8 @@ public class SpelEvaluatingMethodInterceptorUnitTests {
when(invocation.getMethod()).thenReturn(Projection.class.getMethod("propertyFromTarget"));
MethodInterceptor interceptor = new SpelEvaluatingMethodInterceptor(delegate, new Target(), null);
MethodInterceptor interceptor = new SpelEvaluatingMethodInterceptor(delegate, new Target(), null, parser,
Projection.class);
assertThat(interceptor.invoke(invocation), is((Object) "property"));
}
@@ -66,7 +71,8 @@ public class SpelEvaluatingMethodInterceptorUnitTests {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
factory.registerSingleton("someBean", new SomeBean());
SpelEvaluatingMethodInterceptor interceptor = new SpelEvaluatingMethodInterceptor(delegate, new Target(), factory);
SpelEvaluatingMethodInterceptor interceptor = new SpelEvaluatingMethodInterceptor(delegate, new Target(), factory,
parser, Projection.class);
assertThat(interceptor.invoke(invocation), is((Object) "value"));
}
@@ -80,7 +86,7 @@ public class SpelEvaluatingMethodInterceptorUnitTests {
when(invocation.getMethod()).thenReturn(Projection.class.getMethod("getName"));
SpelEvaluatingMethodInterceptor interceptor = new SpelEvaluatingMethodInterceptor(delegate, new Target(),
new DefaultListableBeanFactory());
new DefaultListableBeanFactory(), parser, Projection.class);
interceptor.invoke(invocation);
@@ -93,10 +99,10 @@ public class SpelEvaluatingMethodInterceptorUnitTests {
@Test(expected = IllegalStateException.class)
public void rejectsEmptySpelExpression() throws Throwable {
when(invocation.getMethod()).thenReturn(Projection.class.getMethod("getAddress"));
when(invocation.getMethod()).thenReturn(InvalidProjection.class.getMethod("getAddress"));
SpelEvaluatingMethodInterceptor interceptor = new SpelEvaluatingMethodInterceptor(delegate, new Target(),
new DefaultListableBeanFactory());
new DefaultListableBeanFactory(), parser, InvalidProjection.class);
interceptor.invoke(invocation);
}
@@ -113,7 +119,7 @@ public class SpelEvaluatingMethodInterceptorUnitTests {
when(invocation.getMethod()).thenReturn(Projection.class.getMethod("propertyFromTarget"));
SpelEvaluatingMethodInterceptor interceptor = new SpelEvaluatingMethodInterceptor(delegate, map,
new DefaultListableBeanFactory());
new DefaultListableBeanFactory(), parser, Projection.class);
assertThat(interceptor.invoke(invocation), is((Object) "Dave"));
}
@@ -128,6 +134,11 @@ public class SpelEvaluatingMethodInterceptorUnitTests {
String getName();
String getAddress();
}
interface InvalidProjection {
@Value("")
String getAddress();
}