The concept and function of agent in program
To add some system functionality to the various methods that already exist for the target class with the same interface, such as Exception handling, logging, calculation method run time, transaction management, and so On.
Proxy Architecture Diagram:
If you are managing with Factory mode and configuration files, you do not need to modify the client program, whether you want to use the target class or the proxy class in the configuration file .
This makes it easy to switch, for example, to configure the proxy class when you want the log function, otherwise configure the target class, which makes it easy to add system Functionality.
1. Function and principle of analysis agent class and AOP concept
Agent is the core and key technology to realize AOP Function.
There is cross-service in the system, and a cross-service is to cut into one aspect of the System.
security, transactions, logs and other functions to penetrate into several modules, so they are cross-service
Describe the Cross-service with specific program code:
The Cross-service programming problem is the aspect-oriented change (Aspect oriented program, The goal of the abbreviation AOP,AOP is to make the Cross-service modular. You can move the slice code around the original Method. )
2. Dynamic Agent Technology
The > JVM can dynamically generate byte codes for classes at run time, and this dynamically generated class is often used as a proxy class, which is a dynamic proxy class.
> the dynamic class generated by the JVM must implement one or more interfaces , so the dynamic classes generated by the JVM can only be used as proxies for target classes with the same interface.
* If the target class does not implement an interface, you want to build the proxy using CGLIB
The > CGLIB Library can dynamically generate subclasses of a class, and subclasses of a class can also be used as proxies for that class, so if you want to generate a dynamic proxy class for a class that does not implement an interface, you can use the CGLIB library.
The various methods of the > proxy class are usually in addition to the corresponding methods to invoke the target and return the results returned by the external target, you can also add the system function code in the following four locations in the proxy method:
> 1. Before calling the target method
> 2. After calling the target method
> 3. Before and after calling the target method
> 4. In the catch block that handles the exception of the target method
void SayHello () { ... ..... Try { Target.sayhello (); } Catch (Exception e) { ... }....} ................. }
Create a dynamic class and view its method list information
Analyzing the dynamically generated classes of the JVM
Create a dynamic class that implements the collection interface and view its name, analyzing the parameters of the Proxy.getproxyclass method.
Encoding lists all construction methods and parameter signatures in a dynamic class
Encoding lists all methods and signatures in a dynamic class
To create an instance object of a dynamic class
> Using reflection to obtain a construction method
> Write one of the simplest invocationhandler class
> calls the construction method to create an instance object of the dynamic class, and passes the instance object of the Invocationhandler class written in
> Print created objects and call objects do not return worthwhile methods and GetClass methods, calling other methods with return values throws an Exception.
public classProxytest { public Static voidmain (string[] Args) {//1. create a dynamic class before creating an instance object
Class clazzProxy1= Proxy.getproxyclass (Collection.class. getClassLoader (), Collection.class); System.out.println (clazzproxy1.getname ()); System.out.println ("-----------begin Constructors list"); /*$Proxy 0 () $Proxy 0 (invocationhandler,int)*/constructor[] Constructors= Clazzproxy1.getconstructors ();//returns all the constructor methods for(Constructor constructor:constructors) {String name=Constructor.getname (); StringBuilder Sbuilder=NewStringBuilder (name); Sbuilder.append ("("); class[] Clazzparams= Constructor.getparametertypes ();//returns all the parameter list types for(Class clazzparam:clazzparams) {sbuilder.append (clazzparam.getname ()). Append (","); } if(clazzparams!=NULL&& clazzparams.length! = 0) {sbuilder.deletecharat (clazzparams.length-1);//remove the last one,} sbuilder.append (")"); System.out.println (sbuilder.tostring ()); } System.out.println ("-----------begin Methods list"); /*$Proxy 0 () $Proxy 0 (invocationhandler,int)*/method[] Methods= Clazzproxy1.getmethods ();//return all the methods for(Method method:methods) {String name=Method.getname (); StringBuilder Sbuilder=NewStringBuilder (name); Sbuilder.append ("("); class[] Clazzparams= Method.getparametertypes ();//returns all the parameter list types for(Class clazzparam:clazzparams) {sbuilder.append (clazzparam.getname ()). Append (","); } if(clazzparams!=NULL&& clazzparams.length! = 0) {sbuilder.deletecharat (sbuilder.length ()-1);//remove the last one,} sbuilder.append (")"); System.out.println (sbuilder.tostring ()); } }}
> Internal features of Invocationhandler objects
Constructor Constructor =clazzProxy1. getconstructor (invocationhandler.class); classMyInvocationHander1ImplementsInvocationhandler {@Override publicObject Invoke (object proxy, method method, object[] Args)throwsThrowable {//TODO auto-generated Method Stub return NULL; }} Collection proxy1=(Collection) Constructor. newinstance (NewMyInvocationHander1 ()); System.out.println (proxy1); //This return is NULL because proxy1.tostring () is nullProxy1.clear (); //proxy1.size ();//an exception is thrown because of a return valueCollection Proxy2=(Collection) Constructor. newinstance (NewInvocationhandler () {@Override publicObject Invoke (object proxy, method method, object[] Args)throwsThrowable {//TODO auto-generated Method Stub return NULL; } }); //2. Instantiate an object directly when creating a dynamic classCollection Proxy3 =(Collection) proxy.newproxyinstance (Collection.class. getClassLoader (),Newclass[] {Collection.class},Newinvocationhandler () {ArrayList Target=NewArraylist<>(); @Override publicObject Invoke (object proxy, method method, object[] Args)throwsThrowable {LongStartTime =System.currenttimemillis (); Object Object=Method.invoke (target, args); LongEndTime =System.currenttimemillis (); System.out.println (method.getname ()+ "running time" + (endTime-startTime)); returnobject; } }); Proxy3.add ("zxx"); Proxy3.add ("lhm"); Proxy3.add ("bxd"); System.out.println (proxy3.size ());
/**
* $proxy 0 Why the return is not ArrayList but an agent
* Because GetClass () is inherited from object, only three methods in object are given to handler processing hashcode,equals,tostring
* So when calling GetClass (), the return is self-fulfilling
*/
System.out.println (proxy3.getclass (). getName ());
> How Invocationhandler objects work
When the client program calls the Objproxy.add ("abc") method, it involves three elements: the Objproxy object, the add method, the "abc" parameter
Class proxy${
Add (object Object) {
Return Handler.invoke (Object proxy, method method, object[] args);
}
}
> plane-oriented programming:
The code of the slice, encapsulated in the form of an object, is passed to you as an object, and as long as you execute the object, you execute the code of the Slice.
> Writing generic methods for generating proxies and inserting advertisements
Collection Proxy3 = (Collection) getproxy (new arraylist<> (),new myadvice ()); // once per call, The Invoke method of Invocationhandler is called once Proxy3.add ("zxx"); Proxy3.add ("lhm"); Proxy3.add ("bxd"); System.out.println (proxy3.size ());
GetProxy method
Private StaticObject GetProxy (FinalObject target,FinalMyadvice Advice) {Object Proxy3=proxy.newproxyinstance (target.getclass (). getclassloader (), target.getclass (). getinter Faces (),NewInvocationhandler () {@Override publicObject Invoke (object proxy, method method, object[] Args)throwsthrowable {advice.beforemethod (method); Object Object=Method.invoke (target, args); Advice.aftermethod (method); returnobject; } }); returnproxy3; }
Myadvice class:
public class myadvice implements Advice { long< /span> startTime = 0; @Override public void beforemethod (method) {startTime = System.currenttimemi Llis (); @Override public void long endTime = System.currenttimemillis (); System.out.println (method.getname () + "running time of" + (endTime- startTime)); }}
The goal is to escape both the agent and the system function as an outer object.
Finish spring only one thing: write myadvice, target is configured in the configuration file
Java high-tech-agent