My plan is to create an annotation-based caching framework that caches method return values. When a method is called for the first time with a specific parameter, the cache must store the return value of the methods. When the same method is called a second time with the same parameter, then the method should return the previously calculated result from the cache and not execute its code again. My annotations are as follows:
@Cached(cacheProvider = HashMapCacheProvider.class) public Product getProduct(String productId){ // Scraping the product from a website ... return product; }
At the moment, my little structure is already working fine. I use Javassist to create proxy objects of classes containing annotated methods. To create a new cached object, I use this code:
public static <T> T newCachedInstance(Class<T> clazz) throws InstantiationException, IllegalAccessException { ProxyFactory factory = new ProxyFactory(); factory.setSuperclass(clazz); factory.setFilter(new MethodFilter() { public boolean isHandled(Method m) { // ignore finalize() return !m.getName().equals("finalize"); } }); Class<T> c = factory.createClass(); T proxy = c.newInstance(); ((ProxyObject) proxy).setHandler(new CachedMethodHandler()); return proxy; }
, , . .
: ? , .
- -, :
public class Hello { public void say() { System.out.println("Hello"); } } public class Test { public static void main(String[] args) throws Exception { ClassPool cp = ClassPool.getDefault(); CtClass cc = cp.get("Hello"); CtMethod m = cc.getDeclaredMethod("say"); m.insertBefore("{ System.out.println(\"Hello.say():\"); }"); Class c = cc.toClass(); Hello h = (Hello)c.newInstance(); h.say(); } }
- ? ?
Java , Class ( , ). , , Class, .
Class
sun.misc.Unsafe , . , , , , . , sun , .
sun.misc.Unsafe
sun
API- Attach. Java. , , , .
- - AspectJ .
, - , , -, . , , Hibernate. , javassist , , , cglib, , , . .
https://github.com/verhas/djcproxy , . , , .
https://javax0.wordpress.com/2016/02/03/creating-proxy-object-using-djcproxy/ :
(*), , - , .
(*)
EDIT , djcproxy .
, , , , , :
If you have a copy constructor, you can use it to create a proxy copy of an existing object. (You will need to define it as X$Proxy(X x) {super(x);})
X$Proxy(X x) {super(x);}