Attach a proxy to an existing object?

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();
    }
}

- ? ?

+4
3

Java , Class ( , ). , , Class, .

sun.misc.Unsafe , . , , , , . , sun , .

API- Attach. Java. , , , .

- - AspectJ .

, - , , -, . , , Hibernate. , javassist , , , cglib, , , . .

+1

, , , , , :

  • - Javassist;
  • create an instance of this class (this assumes that there is a constructor with no arguments)
  • copy all fields to this new instance
  • replace the original link (s) with the link (s) to the new object

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);})

+1
source

All Articles