Skip to content

Commit 321dd80

Browse files
YongwuHemr3
authored andcommitted
feat: add spring cache filter (#172)
1 parent cab7e95 commit 321dd80

File tree

4 files changed

+118
-3
lines changed

4 files changed

+118
-3
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package io.arex.inst.cache.spring;
2+
3+
import io.arex.inst.runtime.config.Config;
4+
import io.arex.inst.runtime.context.ContextManager;
5+
import io.arex.inst.runtime.model.DynamicClassEntity;
6+
7+
import java.lang.reflect.Method;
8+
9+
public class SpringCacheAdviceHelper {
10+
public static boolean needRecordOrReplay(Method method) {
11+
if (!ContextManager.needRecordOrReplay() || method == null) {
12+
return false;
13+
}
14+
15+
String methodSignature = buildMethodSignature(method);
16+
17+
DynamicClassEntity dynamicEntity = Config.get().getDynamicEntity(methodSignature);
18+
19+
return dynamicEntity != null;
20+
}
21+
22+
private static String buildMethodSignature(Method method) {
23+
String className = method.getDeclaringClass().getName();
24+
String methodName = method.getName();
25+
Class<?>[] parameterTypes = method.getParameterTypes();
26+
if (parameterTypes.length == 0) {
27+
return className + methodName;
28+
}
29+
return className + methodName + parameterTypes.length;
30+
}
31+
}

arex-instrumentation/dynamic/arex-cache/src/main/java/io/arex/inst/cache/spring/SpringCacheInstrumentation.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,12 @@ public static boolean onEnter(@Advice.Argument(2) Method method,
4646
return false;
4747
}
4848

49-
if (ContextManager.needRecordOrReplay()) {
49+
if (SpringCacheAdviceHelper.needRecordOrReplay(method)) {
5050
Cacheable cacheable = method.getDeclaredAnnotation(Cacheable.class);
5151
String keyExpression = cacheable != null ? cacheable.key() : null;
5252
extractor = new DynamicClassExtractor(method, args, keyExpression, null);
5353
}
54-
if (ContextManager.needReplay()) {
54+
if (extractor != null && ContextManager.needReplay()) {
5555
mockResult = extractor.replay();
5656
return mockResult != null && mockResult.notIgnoreMockResult();
5757
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package io.arex.inst.cache.spring;
2+
3+
import static org.junit.jupiter.api.Assertions.*;
4+
5+
import io.arex.inst.runtime.config.ConfigBuilder;
6+
import io.arex.inst.runtime.context.ContextManager;
7+
import io.arex.inst.runtime.model.DynamicClassEntity;
8+
import java.lang.reflect.Method;
9+
import java.util.ArrayList;
10+
import java.util.List;
11+
import org.junit.jupiter.api.AfterAll;
12+
import org.junit.jupiter.api.BeforeAll;
13+
import org.junit.jupiter.api.Test;
14+
import org.mockito.Mockito;
15+
16+
class SpringCacheAdviceHelperTest {
17+
@BeforeAll
18+
static void setUp() {
19+
Mockito.mockStatic(ContextManager.class);
20+
}
21+
22+
@AfterAll
23+
static void tearDown() {
24+
Mockito.clearAllCaches();
25+
}
26+
27+
@Test
28+
void needRecordOrReplay() throws NoSuchMethodException {
29+
final Method method1 = SpringCacheAdviceHelperTest.class.getDeclaredMethod("method1");
30+
final ConfigBuilder configBuilder = ConfigBuilder.create("test");
31+
configBuilder.build();
32+
33+
// not need record or replay
34+
Mockito.when(ContextManager.needRecordOrReplay()).thenReturn(false);
35+
final boolean needRecordOrReplay = SpringCacheAdviceHelper.needRecordOrReplay(method1);
36+
assertFalse(needRecordOrReplay);
37+
38+
// null method
39+
final boolean nullMethod = SpringCacheAdviceHelper.needRecordOrReplay(null);
40+
assertFalse(nullMethod);
41+
42+
Mockito.when(ContextManager.needRecordOrReplay()).thenReturn(true);
43+
// no dynamic class
44+
final boolean noDynamicClass = SpringCacheAdviceHelper.needRecordOrReplay(method1);
45+
assertFalse(noDynamicClass);
46+
47+
// has dynamic class, but not contains method
48+
final List<DynamicClassEntity> entities = new ArrayList<>();
49+
entities.add(new DynamicClassEntity("io.arex.inst.cache.spring.SpringCacheAdviceHelperTest", null, null, null));
50+
configBuilder.dynamicClassList(entities).build();
51+
final boolean notContainsMethod = SpringCacheAdviceHelper.needRecordOrReplay(method1);
52+
assertFalse(notContainsMethod);
53+
54+
// has no args dynamic class, and contains method
55+
entities.add(new DynamicClassEntity("io.arex.inst.cache.spring.SpringCacheAdviceHelperTest", "method1", null, null));
56+
configBuilder.dynamicClassList(entities).build();
57+
final boolean containsMethod = SpringCacheAdviceHelper.needRecordOrReplay(method1);
58+
assertTrue(containsMethod);
59+
60+
// has args dynamic class, and contains method
61+
final Method method2 = SpringCacheAdviceHelperTest.class.getDeclaredMethod("method2",
62+
String.class);
63+
entities.add(new DynamicClassEntity("io.arex.inst.cache.spring.SpringCacheAdviceHelperTest", "method2", "java.lang.String", null));
64+
configBuilder.dynamicClassList(entities).build();
65+
final boolean containsMethod2 = SpringCacheAdviceHelper.needRecordOrReplay(method2);
66+
assertTrue(containsMethod2);
67+
}
68+
69+
public void method1() {
70+
71+
}
72+
73+
public void method2(String arg1) {
74+
75+
}
76+
}

arex-instrumentation/dynamic/arex-cache/src/test/java/io/arex/inst/cache/spring/SpringCacheInstrumentationTest.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package io.arex.inst.cache.spring;
22

33
import static org.junit.jupiter.api.Assertions.*;
4+
import static org.mockito.ArgumentMatchers.any;
5+
46
import io.arex.agent.bootstrap.model.MockResult;
57
import io.arex.inst.cache.TestArexMock;
68
import io.arex.inst.dynamic.common.DynamicClassExtractor;
@@ -29,6 +31,7 @@ static void setUp() {
2931
Mockito.mockStatic(ContextManager.class);
3032
Mockito.mockStatic(MockUtils.class);
3133
Mockito.mockStatic(RepeatedCollectManager.class);
34+
Mockito.mockStatic(SpringCacheAdviceHelper.class);
3235
}
3336

3437
@AfterAll
@@ -59,8 +62,13 @@ void onEnter() throws NoSuchMethodException {
5962
boolean actualResult = SpringCacheInstrumentation.SpringCacheAdvice.onEnter(testReturnVoid, null, null, null);
6063
assertFalse(actualResult);
6164

65+
// not record
66+
Mockito.when(SpringCacheAdviceHelper.needRecordOrReplay(any())).thenReturn(false);
67+
actualResult = SpringCacheInstrumentation.SpringCacheAdvice.onEnter(test1, new Object[]{ "name", 18 }, null, null);
68+
assertFalse(actualResult);
69+
6270
// record
63-
Mockito.when(ContextManager.needRecordOrReplay()).thenReturn(true);
71+
Mockito.when(SpringCacheAdviceHelper.needRecordOrReplay(any())).thenReturn(true);
6472
Mockito.when(ContextManager.needRecord()).thenReturn(true);
6573
DynamicClassExtractor extractor = new DynamicClassExtractor(test1, new Object[]{"mock"}, "#val", null);
6674
actualResult = SpringCacheInstrumentation.SpringCacheAdvice.onEnter(test1, new Object[]{ "name", 18 }, extractor, null);

0 commit comments

Comments
 (0)