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 thingslogging
,timer
.dynamicproxyhanlder
- delegates requestinvocationchain
.
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
Post a Comment