java - How to create chain of dynamic proxies? -


i create 2 invocationhandler, 1 logging purpose , other 1 measuring time. each on works not know how create chain of these two, both executed. thought enough example logginginvocationhandler extends timerinvocationhandler

    public class dynamicproxymain {  public static void main(string[] args) {     system.out.println("starting dynamic proxy sample");      subjectinterface timerproxy = (subjectinterface) proxy.newproxyinstance(subjectinterface.class.getclassloader(),             new class<?>[]{subjectinterface.class},             new timerinvocationhandler(new subjectinterfaceimpl()));      subjectinterface logginproxy = (subjectinterface) proxy.newproxyinstance(subjectinterface.class.getclassloader(),             new class<?>[]{subjectinterface.class},             new logginginvocationhandler(new subjectinterfaceimpl()));     timerproxy.methoda("a");     timerproxy.methodb("test b");     timerproxy.methodc(1, "test c");  } }  public class logginginvocationhandler implements invocationhandler { object impl; string classname = this.getclass().getcanonicalname();  public logginginvocationhandler(object impl){     this.impl = impl;  } public object invoke(object proxy, method method, object[] args) throws throwable {     object retval;     system.out.println("logginghandler:" + this.getclass().getname() + " has been called");     retval = method.invoke(impl, args);     system.out.println("logginghandler:" + this.getclass().getname() + " has ended");     return retval;  } }    public class timerinvocationhandler extends logginginvocationhandler          implements invocationhandler{ private object impl;  public timerinvocationhandler(object impl) {     super(impl);     this.impl = impl; }  public object invoke(object proxy, method method, object[] args) throws throwable {      object retval = null;     system.out.println("getting duration time method " + method.getname());     long duration = -system.currenttimemillis();     retval = super.invoke(proxy,method,args);     duration += system.currenttimemillis();     system.out.println("it took " + duration + " milliseconds");     system.out.println("duration time handler has ended");     return retval; } } 

actually solved it, both invocationhandlers called. edited post working code

the idea bears similarity intercepting filter, i'll give implementation of it, modified in order work dynamicproxyhandler, if you're interested , want more details, should read link thoroughly.

participants:

  • invocationchain - responsible dispatching invocations.
  • invocation - should put things logging , timer.
  • dynamicproxyhanlder - delegates request invocationchain.

implementaiton:

dynamicproxyhandler.java

public class dynamicproxyhandler implements invocationhandler {     private object proxied;     invocationchain chain = new invocationchainimp();      dynamicproxyhandler(object proxied) {         this.proxied = proxied;     }      @override     public object invoke(object proxy, method method, object[] args) throws throwable {         return chain.invoke(proxied, method, args);     }  } 

invocation.java

public interface invocation {     object invoke(object callee, method method, object[] args, invocationchain chain); } 

invocationchain.java

public interface invocationchain {     public object invoke(object callee, method method, object[] args); } 

invocationchainimp.java

public class invocationchainimp implements invocationchain {     list<invocation> list = new arraylist<>();     object result;     iterator<invocation> tasks;      invocationchainimp() {         list.add(new logginginvocation());         list.add(new timerinvocation());         list.add(new finalinvocation());         tasks = list.iterator();     }      @override     public object invoke(object callee, method method, object[] args) {         if (tasks.hasnext()) {             object result = tasks.next().invoke(callee, method, args, this);             this.result = (this.result == null ? result : this.result);         }         return this.result;     } 

last not least, want define custom classes must confined invocation interface logging, timer, etc.

logginginvocation.java

public class logginginvocation implements invocation {     @override     public object invoke(object callee, method method, object[] args, invocationchain chain) {         chain.invoke(callee, method, args);         logger.getlogger(this.getclass().getcanonicalname()).info(method.getname() + "() execution logged!");         return null;     } } 

timerinvocation.java

public class timerinvocation implements invocation {     @override     public object invoke(object callee, method method, object[] args, invocationchain chain) {         long start_time = system.nanotime();         chain.invoke(callee, method, args);         long end_time = system.nanotime();          system.out.println("timer: excution took " + (end_time - start_time) / 1e6 + "ms");          return null;     } } 

finalinvocation.java request invoked on proxied instance.

public class finalinvocation implements invocation {     @override     public object invoke(object callee, method method, object[] args, invocationchain chain) {         try {             return method.invoke(callee, args);         } catch (illegalaccessexception e) {             e.printstacktrace();         } catch (illegalargumentexception e) {             e.printstacktrace();         } catch (invocationtargetexception e) {             e.printstacktrace();         }          return null;     } } 

rest of code trivial, it's used prove implementation works.
you can stop reading now if want write own.

subjectinterface.java

public interface subjectinterface {     string hello(); } 

subjectinterfaceimp.java

public class subjectinterfaceimp implements subjectinterface {     @override     public string hello() {         system.out.println("in subjectinterfaceimp: greeting!");         return "hello";     } } 

main.java

public class main {     public static void main(string[] args) throws exception {         subjectinterface subject = (subjectinterface) proxy.newproxyinstance(                 subjectinterface.class.getclassloader(),                 new class[] { subjectinterface.class }, new dynamicproxyhandler(new subjectinterfaceimp()));         system.out.println("in main: subject.hello() = " + subject.hello());     } } 

okay, have enough of code, it's show time, let's see got, voila!

in subjectinterfaceimp: greeting! timer: excution took 0.532198ms 九月 02, 2016 12:37:36 下午 logginginvocation invoke 信息: hello() execution logged! in main: subject.hello() = hello 

Comments