From d3f2dd43f58398dfb130d4c446cbdde711a370e6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cidpeng=E2=80=9D?= <630606938@qq.com>
Date: Sat, 23 Oct 2021 23:17:06 +0800
Subject: [PATCH 1/3] =?UTF-8?q?=E5=9F=BA=E4=BA=8E=E6=B3=A8=E8=A7=A3?=
=?UTF-8?q?=E7=9A=84=E7=BC=93=E5=AD=98=E8=A3=85=E9=A5=B0=E5=99=A8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 5 +
.../com/github/hcsp/annotation/Cache.java | 4 +
.../hcsp/annotation/CacheClassDecorator.java | 101 +++++++++++++++++-
.../github/hcsp/annotation/DataService.java | 2 +-
4 files changed, 110 insertions(+), 2 deletions(-)
diff --git a/pom.xml b/pom.xml
index cf436d9..381e3c3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -76,6 +76,11 @@
5.6.0
test
+
+ net.bytebuddy
+ byte-buddy
+ 1.11.21
+
diff --git a/src/main/java/com/github/hcsp/annotation/Cache.java b/src/main/java/com/github/hcsp/annotation/Cache.java
index b8651b5..63febca 100644
--- a/src/main/java/com/github/hcsp/annotation/Cache.java
+++ b/src/main/java/com/github/hcsp/annotation/Cache.java
@@ -1,5 +1,9 @@
package com.github.hcsp.annotation;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
public @interface Cache {
// 标记缓存的时长(秒),默认60s
int cacheSeconds() default 60;
diff --git a/src/main/java/com/github/hcsp/annotation/CacheClassDecorator.java b/src/main/java/com/github/hcsp/annotation/CacheClassDecorator.java
index fb5d531..8f666f6 100644
--- a/src/main/java/com/github/hcsp/annotation/CacheClassDecorator.java
+++ b/src/main/java/com/github/hcsp/annotation/CacheClassDecorator.java
@@ -1,5 +1,16 @@
package com.github.hcsp.annotation;
+import net.bytebuddy.ByteBuddy;
+import net.bytebuddy.implementation.MethodDelegation;
+import net.bytebuddy.implementation.bind.annotation.*;
+import net.bytebuddy.matcher.ElementMatchers;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Objects;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+
public class CacheClassDecorator {
// 将传入的服务类Class进行增强
// 使得返回一个具有如下功能的Class:
@@ -7,8 +18,94 @@ public class CacheClassDecorator {
// 这意味着,在短时间内调用同一个服务的同一个@Cache方法两次
// 它实际上只被调用一次,第二次的结果直接从缓存中获取
// 注意,缓存的实现需要是线程安全的
+ @SuppressWarnings("unchecked")
public static Class decorate(Class klass) {
- return klass;
+ return (Class) new ByteBuddy()
+ .subclass(klass)
+ .method(ElementMatchers.isAnnotatedWith(Cache.class))
+ .intercept(MethodDelegation.to(CacheAdvisor.class))
+ .make()
+ .load(klass.getClassLoader())
+ .getLoaded();
+ }
+
+ private static class CacheKey {
+ private final Object thisObject;
+ private final String methodName;
+ private final Object[] arguments;
+
+ private CacheKey(Object thisObject, String methodName, Object[] arguments) {
+ this.thisObject = thisObject;
+ this.methodName = methodName;
+ this.arguments = arguments;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ CacheKey cacheKey = (CacheKey) o;
+ return Objects.equals(thisObject, cacheKey.thisObject) && Objects.equals(methodName, cacheKey.methodName) && Arrays.equals(arguments, cacheKey.arguments);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = Objects.hash(thisObject, methodName);
+ result = 31 * result + Arrays.hashCode(arguments);
+ return result;
+ }
+ }
+
+ private static class CacheValue {
+ private final Object value;
+ private final long time;
+
+ private CacheValue(Object value, long time) {
+ this.value = value;
+ this.time = time;
+ }
+ }
+
+ public static class CacheAdvisor {
+ private static final ConcurrentHashMap cache = new ConcurrentHashMap<>();
+
+ @RuntimeType
+ public static Object cache(
+ @SuperCall Callable