diff --git a/src/main/java/org/redisson/RedissonAttachedLiveObjectService.java b/src/main/java/org/redisson/RedissonAttachedLiveObjectService.java
index b87aeb565..9f333cd96 100644
--- a/src/main/java/org/redisson/RedissonAttachedLiveObjectService.java
+++ b/src/main/java/org/redisson/RedissonAttachedLiveObjectService.java
@@ -1,18 +1,18 @@
package org.redisson;
-import java.lang.reflect.Field;
import java.util.Map;
import net.bytebuddy.ByteBuddy;
-import net.bytebuddy.description.ByteCodeElement;
import net.bytebuddy.description.field.FieldDescription;
import net.bytebuddy.description.field.FieldList;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
import net.bytebuddy.implementation.FieldAccessor;
import net.bytebuddy.implementation.MethodDelegation;
-import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.matcher.ElementMatchers;
+import org.redisson.core.RExpirable;
+import org.redisson.core.RExpirableAsync;
import org.redisson.core.RObject;
+import org.redisson.core.RObjectAsync;
import org.redisson.liveobject.CodecProvider;
import org.redisson.liveobject.LiveObjectTemplate;
import org.redisson.liveobject.RAttachedLiveObjectService;
@@ -20,6 +20,7 @@ import org.redisson.liveobject.RLiveObject;
import org.redisson.liveobject.annotation.REntity;
import org.redisson.liveobject.annotation.RId;
import org.redisson.liveobject.core.AccessorInterceptor;
+import org.redisson.liveobject.core.ExpirableInterceptor;
import org.redisson.liveobject.misc.Introspectior;
public class RedissonAttachedLiveObjectService implements RAttachedLiveObjectService {
@@ -95,8 +96,18 @@ public class RedissonAttachedLiveObjectService implements RAttachedLiveObjectSer
.and(ElementMatchers.isGetter().or(ElementMatchers.isSetter())))
.intercept(FieldAccessor.ofBeanProperty())
.implement(RLiveObject.class)
+ .method(ElementMatchers.isDeclaredBy(RExpirable.class)
+ .or(ElementMatchers.isDeclaredBy(RExpirableAsync.class))
+ .or(ElementMatchers.isDeclaredBy(RObject.class))
+ .or(ElementMatchers.isDeclaredBy(RObjectAsync.class)))
+ .intercept(MethodDelegation.to(new ExpirableInterceptor()))
+ .implement(RExpirable.class)
.method(ElementMatchers.not(ElementMatchers.isDeclaredBy(Object.class))
.and(ElementMatchers.not(ElementMatchers.isDeclaredBy(RLiveObject.class)))
+ .and(ElementMatchers.not(ElementMatchers.isDeclaredBy(RExpirable.class)))
+ .and(ElementMatchers.not(ElementMatchers.isDeclaredBy(RExpirableAsync.class)))
+ .and(ElementMatchers.not(ElementMatchers.isDeclaredBy(RObject.class)))
+ .and(ElementMatchers.not(ElementMatchers.isDeclaredBy(RObjectAsync.class)))
.and(ElementMatchers.isGetter()
.or(ElementMatchers.isSetter()))
.and(ElementMatchers.isPublic()))
diff --git a/src/main/java/org/redisson/liveobject/LiveObjectTemplate.java b/src/main/java/org/redisson/liveobject/LiveObjectTemplate.java
index 408e1a1ca..38f46e8ac 100644
--- a/src/main/java/org/redisson/liveobject/LiveObjectTemplate.java
+++ b/src/main/java/org/redisson/liveobject/LiveObjectTemplate.java
@@ -8,43 +8,8 @@ import org.redisson.core.RMap;
*/
public class LiveObjectTemplate implements RLiveObject {
- private Long liveObjectTTL;
- private Object liveObjectId;
private RMap liveObjectLiveMap;
- private String liveObjectMapKey;
-
- /**
- * @return the liveObjectTTL
- */
- @Override
- public Long getLiveObjectTTL() {
- return liveObjectTTL;
- }
-
- /**
- * @param liveObjectTTL the liveObjectTTL to set
- */
- @Override
- public void setLiveObjectTTL(Long liveObjectTTL) {
- this.liveObjectTTL = liveObjectTTL;
- }
-
- /**
- * @return the liveObjectId
- */
- @Override
- public Object getLiveObjectId() {
- return liveObjectId;
- }
-
- /**
- * @param liveObjectId the liveObjectId to set
- */
- @Override
- public void setLiveObjectId(Object liveObjectId) {
- this.liveObjectId = liveObjectId;
- }
-
+
/**
* @return the liveObjectLiveMap
*/
@@ -53,29 +18,4 @@ public class LiveObjectTemplate implements RLiveObject {
return liveObjectLiveMap;
}
- /**
- * @param liveObjectLiveMap the liveObjectLiveMap to set
- */
- @Override
- public void setLiveObjectLiveMap(RMap liveObjectLiveMap) {
- this.liveObjectLiveMap = liveObjectLiveMap;
- }
-
- /**
- * @return the liveObjectMapKey
- */
- @Override
- public String getLiveObjectMapKey() {
- return liveObjectMapKey;
- }
-
- /**
- * @param liveObjectMapKey the liveObjectMapKey to set
- */
- @Override
- public void setLiveObjectMapKey(String liveObjectMapKey) {
- this.liveObjectMapKey = liveObjectMapKey;
- }
-
-
}
diff --git a/src/main/java/org/redisson/liveobject/RLiveObject.java b/src/main/java/org/redisson/liveobject/RLiveObject.java
index 7e943e1ff..0372b2e7c 100644
--- a/src/main/java/org/redisson/liveobject/RLiveObject.java
+++ b/src/main/java/org/redisson/liveobject/RLiveObject.java
@@ -8,43 +8,8 @@ import org.redisson.core.RMap;
*/
public interface RLiveObject {
- /**
- * @return the liveObjectTTL
- */
- public Long getLiveObjectTTL();
-
- /**
- * @param liveObjectTTL the liveObjectTTL to set
- */
- public void setLiveObjectTTL(Long liveObjectTTL);
-
- /**
- * @return the LiveObjectId
- */
- public Object getLiveObjectId();
-
- /**
- * @param LiveObjectId the LiveObjectId to set
- */
- public void setLiveObjectId(Object LiveObjectId);
-
/**
* @return the liveObjectLiveMap
*/
public RMap getLiveObjectLiveMap();
-
- /**
- * @param liveObjectLiveMap the liveObjectLiveMap to set
- */
- public void setLiveObjectLiveMap(RMap liveObjectLiveMap);
-
- /**
- * @return the liveObjectMapKey
- */
- public String getLiveObjectMapKey();
-
- /**
- * @param liveObjectMapKey the liveObjectMapKey to set
- */
- public void setLiveObjectMapKey(String liveObjectMapKey);
}
diff --git a/src/main/java/org/redisson/liveobject/core/AccessorInterceptor.java b/src/main/java/org/redisson/liveobject/core/AccessorInterceptor.java
index 355a5d246..4f27f6ec3 100644
--- a/src/main/java/org/redisson/liveobject/core/AccessorInterceptor.java
+++ b/src/main/java/org/redisson/liveobject/core/AccessorInterceptor.java
@@ -1,5 +1,6 @@
package org.redisson.liveobject.core;
+import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
import net.bytebuddy.implementation.bind.annotation.AllArguments;
@@ -20,8 +21,9 @@ import org.redisson.liveobject.annotation.RId;
import org.redisson.liveobject.misc.Introspectior;
/**
- * This class is going to be instantiated and becomes a static field of the proxied
- * target class. That is one instance of this class per proxied class.
+ * This class is going to be instantiated and becomes a static field of
+ * the proxied target class. That is one instance of this class per proxied
+ * class.
*
* @author Rui Gu (https://github.com/jackygurui)
*/
@@ -47,11 +49,10 @@ public class AccessorInterceptor {
@RuntimeType
public Object intercept(@Origin Method method, @SuperCall Callable> superMethod,
@AllArguments Object[] args, @This Object me) throws Exception {
+ RMap liveMap = getLiveMap(me);
if (isGetter(method, idFieldName)) {
return superMethod.call();
}
- String id = getMapKey(getId(me));
- RMap liveMap = redisson.getMap(id, codecProvider.getCodec(codecClass, RedissonMap.class, id));
if (isSetter(method, idFieldName)) {
//TODO: distributed locking maybe required.
try {
@@ -89,6 +90,16 @@ public class AccessorInterceptor {
return superMethod.call();
}
+ private RMap getLiveMap(Object me) throws Exception {
+ RMap liveMap = (RMap) me.getClass().getField("liveObjectLiveMap").get(me);
+ if (liveMap == null) {
+ String id = getMapKey(getId(me));
+ liveMap = redisson.getMap(id, codecProvider.getCodec(codecClass, RedissonMap.class, id));
+ me.getClass().getField("liveObjectLiveMap").set(me, liveMap);
+ }
+ return liveMap;
+ }
+
private String getFieldName(Method method) {
return method.getName().substring(3, 4).toLowerCase() + method.getName().substring(4);
}
diff --git a/src/main/java/org/redisson/liveobject/core/ExpirableInterceptor.java b/src/main/java/org/redisson/liveobject/core/ExpirableInterceptor.java
new file mode 100644
index 000000000..9db57012a
--- /dev/null
+++ b/src/main/java/org/redisson/liveobject/core/ExpirableInterceptor.java
@@ -0,0 +1,137 @@
+package org.redisson.liveobject.core;
+
+import io.netty.util.concurrent.Future;
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+import net.bytebuddy.implementation.bind.annotation.RuntimeType;
+import net.bytebuddy.implementation.bind.annotation.This;
+import org.redisson.client.codec.Codec;
+import org.redisson.liveobject.RLiveObject;
+
+/**
+ *
+ * @author Rui Gu (https://github.com/jackygurui)
+ */
+public class ExpirableInterceptor {
+
+ @RuntimeType
+ public boolean expire(@This Object me, long timeToLive, TimeUnit timeUnit) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @RuntimeType
+ public boolean expireAt(@This Object me, long timestamp) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @RuntimeType
+ public boolean expireAt(@This Object me, Date timestamp) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @RuntimeType
+ public boolean clearExpire(@This Object me) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @RuntimeType
+ public long remainTimeToLive(@This Object me) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @RuntimeType
+ public void migrate(@This Object me, String host, int port, int database) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @RuntimeType
+ public boolean move(@This Object me, int database) {
+ ((RLiveObject) me).getLiveObjectLiveMap().move(database);
+ return true;
+ }
+
+ @RuntimeType
+ public String getName(@This Object me) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @RuntimeType
+ public boolean delete(@This Object me) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @RuntimeType
+ public void rename(@This Object me, String newName) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @RuntimeType
+ public boolean renamenx(@This Object me, String newName) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @RuntimeType
+ public boolean isExists(@This Object me) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @RuntimeType
+ public Codec getCodec(@This Object me) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @RuntimeType
+ public Future migrateAsync(@This Object me, String host, int port, int database) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @RuntimeType
+ public Future moveAsync(@This Object me, int database) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @RuntimeType
+ public Future deleteAsync(@This Object me) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @RuntimeType
+ public Future renameAsync(@This Object me, String newName) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @RuntimeType
+ public Future renamenxAsync(@This Object me, String newName) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @RuntimeType
+ public Future isExistsAsync(@This Object me) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @RuntimeType
+ public Future expireAsync(@This Object me, long timeToLive, TimeUnit timeUnit) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @RuntimeType
+ public Future expireAtAsync(@This Object me, Date timestamp) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @RuntimeType
+ public Future expireAtAsync(@This Object me, long timestamp) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @RuntimeType
+ public Future clearExpireAsync(@This Object me) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @RuntimeType
+ public Future remainTimeToLiveAsync(@This Object me) {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+}