Here the content is more complex, to achieve is toarbitrary interface, for any specified method, and for any specified proxy typeThe agent, it is more realistic to simulate the dynamic agent mechanism of Java Virtual machine
list the relationship between the classes and interfaces involved, so that we could learn.
1, Invocationhandler interface, used to handle the specified method, that is, the agent for a particular method, the implementation of the specific processing by the subclass implementation
2, Timehandler class, implements the Invocationhandler interface sub-class, the specific agent implementation is the time agent
3, proxy class, used to generate the class of proxy class
4, moveable interface, for example, the process of various types to achieve the Unified interface
5, Tank class, implements the moveable interface, that is, the proxy class
6, Cilent, Operation client
First, the whole idea of management:
first, on the client side, new is a Proxied object Tank,tank object as the constructor parameter of the incoming agent processing class timehandler,new out a Timehandler object
The tank interface moveable and Timehandler objects are passed as parameters to the Proxy,proxy call Newproxyinstance method, in which all the methods of the interface are used
Timehandler object for Proxy, (which can be simply understood as combining interface methods with Timehandler proxy methods), generate new proxy objects for Java files, class files,
then load into the memory, using reflection to obtain a proxy object, return the proxy object, the client side calls the proxy object method;
1. Invocationhandler interface
Package com.csu.proxy;
Import Java.lang.reflect.Method;
Custom processing for any method
Method invocation of the processor
Public interface Invocationhandler {//Defines an interface that is used to process the method, and the specific implementation of the processing is referred to the subclass implementation
public void Invoke (Object O, Method m); Handling of a specified method
}
2, Timehandler class
Package com.csu.proxy;
Import Java.lang.reflect.Method;
public class Timehandler implements Invocationhandler {
Private Object target;//The object being proxied
Public Object Gett () {
return target;
}
public void Sett (Object t) {
This.target = t;
}
Public Timehandler (Object target) {
This.target = target;
}
@Override
public void Invoke (object O,method m) {//must specify a specific object's call to a specific method
Long start = System.currenttimemillis ();
System.out.println ("Start time is" + start);
System.out.println (O.getclass (). GetName ());
M Call method
try {
M.invoke (target);
} catch (Exception e) {e.printstacktrace ();}
Long end = System.currenttimemillis ();
System.out.println ("End Time Is" +end);
System.out.println ("Time is" + (End-start));
}
}
3. Moveable interface
Package com.csu.proxy;
public interface Moveable {
void Move ();
}
4, Tank class
Package com.csu.proxy;
Import Java.util.Random;
public class Tank implements moveable {
@Override
public void Move () {
System.out.println ("Tank moving ...");
try {
Thread.Sleep (New Random (). Nextint (10000));
} catch (Interruptedexception e) {
E.printstacktrace ();
}
}
}
5. Proxy class
Package com.csu.proxy;
Import Javax.tools.JavaCompiler;
Import Javax.tools.StandardJavaFileManager;
Import Javax.tools.ToolProvider;
Import Java.io.File;
Import Java.io.FileWriter;
Import Java.lang.reflect.Constructor;
Import Java.lang.reflect.Method;
Import Java.net.URL;
Import Java.net.URLClassLoader;
/**
easy for everyone to read, focus on the main logic ideas, will be in the previous blog has written comments code cleared, because this is a series, there are a lot of code reference
you want to see, go to a few articles to see it
**/
This class is implemented on arbitrary interfaces, arbitrary methods, and arbitrary proxies.
public class ProxyG3 {
public static Object newproxyinstance (Class intf, Invocationhandler h) throws exception{
//invocationhandler, as a parameter, specifies the type of proxy that specifies what to do with the method
//*****************1, obtaining Java files **********************************
String methodsstring = "";
String RT = "\ r \ n";
method[] methods = Intf.getmethods ();
For (Method m:methods) {
methodsstring + = "@Override" + RT +
"public void" + m.getname () + "() {" + RT +
"try {" + RT +
"Method md =" + intf.getname () + ". Class.getmethod (\" "+ m.getname () +" \ ");" + RT +
"H.invoke (this, MD);" + RT +
"}catch (Exception e) {e.printstacktrace ();}" + RT +
"}";
}
String src =
"Package com.csu.proxy;" + RT +
"Import java.lang.reflect.Method;" + RT +
"public class Tanktimeproxy implements" + intf.getname () + "{" + RT +
"Public tanktimeproxy (Invocationhandler h) {" + RT +
"this.h = h;" + RT +
"}" + RT +
"Com.csu.proxy.InvocationHandler h;" + RT +
methodsstring +
"}";
String fileName = "G:/src/com/csu/proxy/tanktimeproxy.java";//place at specified location
File F = new file (fileName);
FileWriter FW = new FileWriter (f);
Fw.write (SRC);
Fw.flush ();
Fw.close ();
/**
Here's the point: the package name of the Java and class files used to hold the proxy object Tanktimeproxy is the same as the package name of the other Java files in the project, so look at the code and you'll find
The package name of the Java file of the project Java file and the generated proxy object is com.csu.proxy;
**/
//****************2, get class file ****************************************
//Get Compiler Object
Javacompiler compiler = Toolprovider.getsystemjavacompiler ();
//Manage dynamically generated files
Standardjavafilemanager FileManager = Compiler.getstandardfilemanager (null,null,null);
Iterable units = filemanager.getjavafileobjects (fileName);
//"Compile Task" object
Javacompiler.compilationtask task = Compiler.gettask (null,filemanager,null,null,null,units);
Task.call ();
Filemanager.close ();
//*****************3, load to memory ******************************************
Introducing local files via URLs
url[] urls = new Url[]{new URL ("file:/" + "g:/src/")}; accessing local Filesspecify where class files are stored
URLClassLoader URLClassLoader = new URLClassLoader (URLs);
Class C = Urlclassloader.loadclass ("Com.csu.proxy.TankTimeProxy");
//******************4, executes the class file, returns the proxy object ***************************************
//Get construction method
Constructor Constructor = C.getconstructor (Invocationhandler.class);the//getconstructor parameter is class type, which is the class type of the parameter of the original construction method
//Generate new objects
Object m = constructor.newinstance (h);
return m;
}
}
6. Cilent Client
Package com.csu.proxy;
public class Client {
public static void Main (string[] args) throws Exception {
Tank t = new Tank ();
Invocationhandler h = new Timehandler (t);
Moveable M = (moveable) proxyg3.newproxyinstance (Moveable.class, h);
M.move ();
}
}
7. Implementation results
(1) Generated Java and class files
(2) View the generated Java file code
(3) Operation result
Deep simulation of Java dynamic Agent implementation Mechanism class three