Java reflection and proxy, Java reflection proxy
Java reflection mechanism and dynamic proxy make Java more powerful. The core concepts of Spring IoC and AOP are implemented through reflection mechanism and dynamic proxy.
1 Java reflection
Example:
User user = new User (); user. setTime5Flag ("test"); Class <?> Cls = Class. forName ("com. test. User"); // The interface must be public, whether or not it is used inside the Class! Or use cls. getDeclaredMethod (), or traverse and modify the accessible Method = cls. getMethod ("getTime5Flag"); String res1 = (String) method. invoke (user); System. out. println (res1); // applies to basic types such as int. class! Integer. class! = Int. class! Method = cls. getMethod ("setTime5Flag", String. class); method. invoke (user, "Rollen"); method = cls. getMethod ("getTime5Flag"); String res2 = (String) method. invoke (user); System. out. println (res2 );
Get the complete package name and class name through an object:
User. getClass (). getName (); // full path Class Name user. getClass (). getSimpleName (); // class name without package name
Get class:
Class.forName("com.test.User");com.test.User.class;user.getClass();
Instantiate an object through class
User user = (User) cls. newInstance (); // required parameter Constructors
Get all Constructors
Constructor <?> Cons [] = cls. getConstructors (); // return cons [0]. newInstance () in the declared order; // if no declaration is displayed, a default constructor is available.
Obtains all interfaces implemented by a class.
Class<?> intes[] = cls.getInterfaces();
Obtain the parent class
cls.getSuperClass();
Get Modifier
int mo = cls.getModifiers();int mo = cons[0].getModifiers();int mo = method.getModifiers();Modifier.toString(mo);
Obtain method parameters
method.getParametors();cons[0].getParametors();
Method parameter type
method.getParametorTypes();cons[0].getParametorTypes();
Obtain all the exception types thrown by the method declaration.
method.getExceptionTypes();
Obtain all attributes declared by this class
Field [] field = cls. getDeclaredFields (); // includes privatefield [0]. getModifiers (); field [0]. getType ();
Obtain all public attributes of this class, including the parent class declaration, interface declaration, and all public attributes of this class declaration.
cls.getFields();
Set the specified attribute to be accessible
field.setAccessible(true);field.set(obj,’ces’);field.get(obj);
* Difference between getFields () and getDeclaredFields (): getFields () can only be declared as a public field in the response class, private fields cannot be accessed, and public fields inherited from other classes can be accessed; getDeclaredFields () can enumerate all fields in the class. It has nothing to do with public, private, and protect, but cannot access fields inherited from other classes.
* Difference between getMethods () and getDeclaredMethods (): getMethods () can only be declared as a public method in the methods class, private methods cannot be accessed, and public methods inherited from other classes can be accessed; getDeclaredMethods () is applicable to all fields in the category class and has nothing to do with public, private, and protect. It cannot access methods inherited from other classes.
* Difference between getConstructors () and getDeclaredConstructors (): getConstructors () can only be a public constructor defined in the declare class; getDeclaredConstructors () can be a constructor in the evaluate class and has nothing to do with public, private
Obtain and modify array information through reflection
Int [] temp = {1, 2, 3, 4, 5}; Class <?> Demo = temp. getClass (). getComponentType (); System. out. println ("array type:" + demo. getName (); // intSystem. out. println ("Array length:" + Array. getLength (temp); // 5System. out. println ("the first element of the Array:" + Array. get (temp, 0); // 1Array. set (temp, 0,100); System. out. println ("the first element of the modified Array is:" + Array. get (temp, 0); // 100.
Obtain the array type
cls.getComponentType();
Determine whether it is an array type
cls.isArray();
2 Java proxy
The proxy mode is a common Java design mode. It features the same interface between the proxy class and the delegate class. The proxy class is mainly responsible for preprocessing, filtering, and forwarding messages to the delegate class, and post-processing messages. There is usually an association between the proxy class and the delegate class. A proxy class object is associated with a delegate class object. The proxy class object itself does not actually implement the service, but calls the relevant methods of the delegate class object, to provide specific services.
According to the agent creation period, the agent class can be divided into two types.
- Static Proxy: the source code is automatically generated by the programmer or a specific tool, and then compiled. Before running the program, the. class file of the proxy class already exists.
- Dynamic Proxy: when the program is running, the Java reflection mechanism dynamically generates bytecode.
2.1 static proxy
Public interface Count {public void queryCount ();} public class CountImpl implements Count {public void queryCount () {System. out. println ("view account method... ") ;}}// proxy class public class CountProxy implements Count {private CountImpl countImpl; public CountProxy (CountImpl countImpl) {this. countImpl = countImpl;} @ Override public void queryCount () {System. out. println ("before transaction processing"); countImpl. queryCount (); // call the delegate class method; System. out. println ("after transaction processing") ;}// test class public class TestCount {public static void main (String [] args) {CountImpl countImpl = new CountImpl (); countProxy countProxy = new CountProxy (countImpl); countProxy. queryCount ();}}
By observing the code, we can find that each proxy class can only serve one interface. In this way, too many Proxies are generated in program development. Besides the called methods, all proxy operations are different, if all other operations are the same, the Code must be repeated. The best way to solve this problem is to use a dynamic proxy to complete all proxy functions through one proxy class.
2.2 dynamic proxy
The bytecode of the dynamic proxy class is dynamically generated by the Java reflection mechanism when the program is running, without the need for programmers to manually write its source code. Dynamic proxy not only simplifies programming, but also improves the scalability of the software system, because the Java reflection mechanism can generate any type of dynamic proxy class.
2.2.1 JDK dynamic proxy
The Proxy class and InvocationHandler interface in the java. lang. reflect package provide the ability to generate dynamic Proxy classes.
InvocationHandler interface:
Public interface InvocationHandler {
Public Object invoke (Object proxy, Method method, Object [] args) throws Throwable;
}
Parameter description:
Object proxy: the proxy Object.
Method method: Method to be called
Object [] args: parameters required for method calling
The subclass of the InvocationHandler interface can be considered as the final operation class of a proxy, replacing ProxySubject.
Proxy class:
The Proxy class is an operation class dedicated to Proxy. You can use this class to dynamically generate an implementation class for one or more interfaces. This class provides the following operation methods:
Public static Object newProxyInstance (ClassLoader loader, Class <?> [] Interfaces, InvocationHandler h) throws IllegalArgumentException
Parameter description:
ClassLoader loader: Class loader
Class <?> [] Interfaces: Get all interfaces
InvocationHandler h: obtains the subclass instance of the InvocationHandler interface.
To complete a dynamic proxy, you must first define a subclass of the InvocationHandler interface to complete specific proxy operations.
Interface Subject {public String say (String name, int age);} class RealSubject implements Subject {@ Override public String say (String name, int age) {return name + "" + age ;}// JDK dynamic proxy class MyInvocationHandler implements InvocationHandler {private Object target = null; // bind the delegate Object and return a proxy class public Object bind (Object target) {this. target = target; return Proxy. newProxyInstance (target. getClass (). getClassLoader (),
Target. getClass (). getInterfaces (), this); // interface to be bound (cglib makes up for this)} @ Override public Object invoke (Object proxy, Method method, Object [] args) throws Throwable {System. out. println ("before method! "); Object temp = method. invoke (target, args); System. out. println ("after method !"); Return temp ;}} class hello {public static void main (String [] args) {MyInvocationHandler demo = new MyInvocationHandler (); Subject sub = (Subject) demo. bind (new RealSubject (); String info = sub. say ("Rollen", 20); System. out. println (info );}}
However, JDK dynamic proxy relies on interfaces. If some classes do not implement interfaces, JDK proxy cannot be used. cglib dynamic proxy is required. 2.2.2 CGLIB dynamic proxy
JDK's dynamic proxy mechanism can only implement interface classes, but those without interfaces cannot implement JDK's dynamic proxy.
Cglib implements proxy for classes. Its principle is:Generates a subclass for the specified target class and overwrites the method to implement enhancement.But because it uses inheritance, it is not allowed to proxy the final modified class.
Public interface BookFacade {public void addBook ();} public class BookFacadeImpl1 {public void addBook () {System. out. println ("add the normal method of books... ") ;}} import java. lang. reflect. method; import net. sf. cglib. proxy. enhancer; import net. sf. cglib. proxy. methodInterceptor; import net. sf. cglib. proxy. methodProxy; // cglib dynamic proxy class public class BookFacadeCglib implements MethodInterceptor {private Object target; // bind the delegate Object and return a proxy class public Object getInstance (Object target) {this.tar get = target; enhancer enhancer = new Enhancer (); enhancer.setSuperclass(this.tar get. getClass (); // callback method enhancer. setCallback (this); // create the proxy object return enhancer. create () ;}@ Override // callback Method public Object intercept (Object obj, method Method, Object [] args, MethodProxy proxy) throws Throwable {System. out. println ("transaction start"); Object temp = proxy. invokeSuper (obj, args); System. out. println (""); return temp;} public class TestCglib {public static void main (String [] args) {BookFacadeCglib cglib = new BookFacadeCglib (); bookFacadeImpl1 bookCglib = (BookFacadeImpl1) cglib. getInstance (new BookFacadeImpl1 (); bookCglib. addBook ();}}
Reference: 1. https://segmentfault.com/a/11900000043260402.http://blog.csdn.net/hintcnuie/article/details/10954631