Reflection and proxy in Java

Java dictionary 2021-02-23 16:57:57
reflection proxy java


Java Reflection mechanism can dynamically get the structure of the class , Dynamically call methods of objects , yes java Language is a dynamic mechanism .java Dynamic proxy can be called without changing the source code of the object , Add your own operations before and after the called method , Greatly reduces the coupling between modules . These are all java Basic knowledge of , To be a qualified programmer , Must master !

Java The reflex mechanism

JAVA The reflection mechanism is in the running state , For any class , Can know all the properties and methods of this class ; For any object , Can call any of its methods and properties ; The function of dynamically obtaining information and dynamically calling methods of objects is called java The reflexive mechanism of language .

Java Reflection mechanism allows programs to judge and analyze the structure of any class at runtime , Including member variables and methods , And call the method of any object .Eclipse You can pop up the object's methods and properties automatically , Using the principle of reflection .Java The dynamic proxy is realized by using the characteristics of reflection .

1、 Get class Class object

1) A.class: Classes will not be loaded , Static code segments are not executed ;

2) Class.forName("cn.test.reflect.A"): requirement JVM Find and load the specified class , in other words JVM Will execute the static code segment of this class ;

3) new A().getClass(): Get... By object class

2、 Reflection creates objects

1) Create objects through the default constructor :Class<?> t = Class.forName("cn.test.reflect.A"); t.newInstance();

2) Create an object by specifying a constructor :Class<?> t = Class.forName("cn.test.reflect.A"); Constructor<?> cons[] = t.getConstructors(); A a = (A) cons[2].newInstance("aa","bb");

notes :

① Class<?> Represents any type of class ;

② newInstance() Method can only call public The parameterless constructor for , It and new Keyword to create instance : Objects are created differently , The former uses class loading mechanism , The latter is to create a new class ;

3、Class Class common methods

getName(): Get the full name of the class ;

getSuperclass(): Get the parent of the class ;

newInstance() : Create an object of this class through its nonparametric construction method ;

getFields() : Get... In the current class and parent class public All properties of the type ;

getDeclaredFields() : Get the current class ( There is no parent class ) All properties declared , Include private and public;

notes : For an attribute field, Set up field.setAccessible(true), Can access private The attribute value , Such as field.get(obj)

getMethods() : Get the previous class and the parent class public All methods of type ;

getDeclaredMethods(): Get the current class ( There is no parent class ) All methods of declaration , Include private and public;

getMethod(String name, Class[] parameterTypes): Get the specified method of the class ,name Parameter specifies the name of the method ,parameterTypes Parameter specifies the parameter type of the method ;

getConstructors() : Get the... Of the current class public Construction method of type ;

getDeclaredConstructors() : Get the... Of the current class public and private Construction method of type ;

getConstructor(Class[] parameterTypes): Get the specific construction method of the class ,parameterTypes Parameter specifies the parameter type of the constructor ;

getInterfaces(): Get the implemented interface ;

getSuperclass() : Get the inherited parent class ;

4、Java Reflection usage examples

ThirdPartyImage_01ef006a.png ThirdPartyImage_29c8068a.png

package com.hicoor.test.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;
class B{
public int b;
public B(){}
}
interface IA{}
class A extends B implements IA{
public A() { }
public A(String str) { }
public A(String str1, String str2) { }
private String str;
public int age;
public int func1(String name) {
System.out.println("hello " + name);
return 8;
}
public void func1(String name1, String name2) {
System.out.println("hello "+name1+","+name2);
}
}
public class ReflectDemo {
public static void main(String[] args) throws Exception {
// Get the class from the string 
Class<?> demoClass = Class.forName("com.hicoor.test.reflect.A");
// Get the full name of the class 
System.out.println(" Class name "+demoClass.getName()); // com.hicoor.test.reflect.A
// Get class loader , Default sun.misc.Launcher$AppClassLoader
System.out.println(" Class loader :"+demoClass.getClassLoader().getClass().getName());
// according to Class To create an instance of 
A newAObj = (A)demoClass.newInstance();
// Get the properties declared in the class 
Field[] publicFields = demoClass.getFields(); // Get... In the current class and parent class public All properties of the type , return :age
Field[] declareFields = demoClass.getDeclaredFields(); // Get the current class ( There is no parent class ) All properties declared , Include private and public, return :str age
Field specifyField = demoClass.getField("age"); // Gets the specified property by name 
specifyField.setAccessible(true);
// Modify properties 
specifyField.set(newAObj, 88);
// The way to get the class 
Method[] publicMethods = demoClass.getMethods(); // Get the previous class and the parent class public All methods of type 
Method[] declareMethods = demoClass.getDeclaredMethods(); // Get the current class ( There is no parent class ) All methods of declaration , Include private and public
Method specifyMethod = demoClass.getDeclaredMethod("func1",new Class<?>[]{java.lang.String.class}); // Get a method according to the method name and method parameter type 
// Reflection calls the method of the object 
specifyMethod.invoke(newAObj, "hans");
// Get constructor 
Constructor<?>[] publicConstructors = demoClass.getConstructors();
Constructor<?>[] declareConstructors = demoClass.getDeclaredConstructors(); // Gets all of the private and public Construction method 
Constructor<?> constructor = demoClass.getConstructor(new Class<?>[]{java.lang.String.class}); // Gets the constructor based on the specified type 
A newAobj2 = (A)constructor.newInstance("hello"); // Create an instance based on the specified constructor 
// Get the implemented interface 
Class<?>[] interfaces = demoClass.getInterfaces();
// Get the inherited parent class 
Class<?> superclass = demoClass.getSuperclass();
}
// Reflection gets a detailed definition of a method 
private static void getMethodDetail(Method method) {
String methodModifier = Modifier.toString(method.getModifiers()); // Method modifier 
String returnType = method.getReturnType().getName(); // Method return value 
Class<?>[] parameterTypes = method.getParameterTypes(); // Method parameter type 
System.out.print(methodModifier+" "+returnType+" "+ method.getName()+"(");
int i=1;
for (Class<?> parameterType : parameterTypes) {
System.out.print(parameterType.getName() + " arg"+(i++));
if(i<=parameterTypes.length){
System.out.print(",");
}
}
System.out.println(") {}");
}
}

JAVA A dynamic proxy

If there is such a demand , Add some unified pre and post-processing operations before and after some module method calls , Like adding a shopping cart 、 Modify orders and other operations before and after the unification, plus login verification and log processing , How to realize it ? First of all, the simplest way is to modify the source code directly , Add operations before and after the corresponding method of the corresponding module . If there are many modules , You'll find that , Modifying the source code is not only very cumbersome 、 Difficult to maintain , And it makes the code look bloated .

At this time, it's the dynamic agent's turn , It can add its own operation before and after the called method through reflection , Without changing the source code of the called class , The coupling between modules is greatly reduced , It shows a great advantage .

1、JDK A dynamic proxy

JDK The dynamic proxy contains a class and an interface , namely Proxy Classes and InvocationHandler Interface .

1) InvocationHandler Interface :

public interface InvocationHandler {
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable;
}

Parameter description :① Object proxy: Refers to the represented object ;② Method method: Method to call ;③ Object[] args: Parameters required for method call ;

2) Proxy class : Proxy Class is the operation class that completes the agent , This class can be used to dynamically generate implementation classes for one or more interfaces , This class provides the following operations .

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException

Parameter description :① ClassLoader loader: Class loader ;② Class<?>[] interfaces: Get all the interfaces ;③ InvocationHandler h: obtain InvocationHandler Subclass instance of interface ;

3) About class loaders

stay Proxy Class newProxyInstance() One of the methods needs to be ClassLoader Class ,ClassLoader It's actually a class loader , stay Java There are three main types of loaders in :

① Booststrap ClassLoader: This loader uses C++ To write , Usually load jre/lib/rt.jar, We can't see it in general development ;

② Extendsion ClassLoader: Used to load extension classes , Usually load jre/lib/ext/*.jar;

③ AppClassLoader:( Default ) load classpath Specified class , Is the most commonly used is a loader ;

4) JDK Dynamic proxy instance :

ThirdPartyImage_e8d3bc62.png ThirdPartyImage_8e9de374.png

package com.hicoor.test.dynamicProxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface Animal {
public void makeSound(String name);
}
class Dog implements Animal {
@Override
public void makeSound(String name) {
System.out.println("Hi," + name + ",wang,wang~~");
}
}
class Cat implements Animal {
@Override
public void makeSound(String name) {
System.out.println("Hi," + name + ",miao,miao~~");
}
}
/**
* @author Hans General dynamic proxy class , This kind of proxy can be used for all classes with the same operation before and after the object method is called
*/
class AnimalProxy implements InvocationHandler {
// The object to be represented 
private Object target;
/**
* Bind the delegate object and return a proxy class
*
* @param target
* @return
*/
public Object getInstance(Object target) {
this.target = target;
// Get the proxy object 
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = null;
System.out.println(" Operation before method call ..");
// Execute the body of the called method 
result = method.invoke(target, args);
System.out.println(" Operation after method call ..");
return result;
}
}
public class DynamicProxyJDKDemo {
public static void main(String[] args) {
AnimalProxy proxy = new AnimalProxy();
Animal dogProxy = (Animal) proxy.getInstance(new Dog());
dogProxy.makeSound("Tom");
}
}

2、Cglib A dynamic proxy

JDK The dynamic proxy mechanism can only implement the class of the interface , Classes that cannot implement interfaces cannot implement JDK Dynamic proxy for ,cglib It's about classes that implement proxies , His principle is to generate a subclass of the specified target class , And cover the methods to realize the enhancement , But because it's inheritance , So we can't be right final Decorated class to proxy .

Use cglib Agents need to download cglib.jar file , Download address :[http://www.java2s.com/Code/Jar/c/Downloadcloudcglibjar.htm][http_www.java2s.com_Code_Jar_c_Downloadcloudcglibjar.htm]

Cglib Dynamic proxy instance :

ThirdPartyImage_8bafaa8c.png ThirdPartyImage_4190cfe3.png

package com.hicoor.test.dynamicProxy;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
class Snake{
public void makeSound(String name) {
System.out.println("Hi," + name + ",si,si~~");
}
}
class AnimalProxyCglib implements MethodInterceptor {
// The object to be represented 
private Object target;
/**
* Create proxy object
*
* @param target
* @return
*/
public Object getInstance(Object target) {
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target.getClass());
// The callback method 
enhancer.setCallback(this);
// Create proxy object 
return enhancer.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
Object result = null;
System.out.println(" Operation before method call ..");
// Execute the body of the called method 
result = proxy.invokeSuper(obj, args);
System.out.println(" Operation after method call ..");
return result;
}
}
public class DynamicProxyCglibDemo {
public static void main(String[] args) {
AnimalProxyCglib proxy = new AnimalProxyCglib();
Snake dogProxy = (Snake) proxy.getInstance(new Snake());
dogProxy.makeSound("Tom");
}
}

Official account :java Treasure a

版权声明
本文为[Java dictionary]所创,转载请带上原文链接,感谢
https://javamana.com/2021/02/20210223165630515i.html

  1. k8s-prometheus
  2. Linux Disk Command
  3. Linux FS
  4. 使用docker-compose &WordPress建站
  5. Linux Command
  6. This time, thoroughly grasp the depth of JavaScript copy
  7. Linux Disk Command
  8. Linux FS
  9. Using docker compose & WordPress to build a website
  10. Linux Command
  11. 摊牌了,我 HTTP 功底贼好!
  12. shiro 报 Submitted credentials for token
  13. It's a showdown. I'm good at it!
  14. Shiro submitted credentials for token
  15. Linux Stress test
  16. Linux Root Disk Extension
  17. Linux Stress test
  18. Linux Root Disk Extension
  19. Redis高级客户端Lettuce详解
  20. springboot学习-综合运用(一)
  21. 忘记云服务器上MySQL数据库的root密码时如何重置密码?
  22. Detailed explanation of lettuce, an advanced client of redis
  23. Springboot learning integrated application (1)
  24. Linux File Recover
  25. Linux-Security
  26. How to reset the password when you forget the root password of MySQL database on the cloud server?
  27. Linux File Recover
  28. Linux-Security
  29. LiteOS:盘点那些重要的数据结构
  30. Linux Memory
  31. Liteos: inventory those important data structures
  32. Linux Memory
  33. 手把手教你使用IDEA2020创建SpringBoot项目
  34. Hand in hand to teach you how to create a springboot project with idea2020
  35. spring boot 整合swagger2生成API文档
  36. Spring boot integrates swagger2 to generate API documents
  37. linux操作系统重启后 解决nginx的pid消失问题
  38. Solve the problem of nginx PID disappearing after Linux operating system restart
  39. JAVA版本号含义
  40. The meaning of java version number
  41. 开源办公开发平台丨Mysql5.7两套四节点主从结构环境搭建教程(二)
  42. 开源办公开发平台丨Mysql5.7两套四节点主从结构环境搭建教程(一)
  43. Open source office development platform mysql5.7 two sets of four node master-slave structure environment building tutorial (2)
  44. HTTP的“无状态”和REST的“状态转换”
  45. Open source office development platform mysql5.7 two sets of four node master-slave structure environment building tutorial (1)
  46. 【大数据哔哔集20210128】使用Hive计算环比和同比
  47. 【大数据哔哔集20210125】Kafka将逐步弃用对zookeeper的依赖
  48. 【大数据哔哔集20210124】有人问我Kafka Leader选举?我真没慌
  49. 【大数据哔哔集20210123】别问,问就是Kafka高可靠
  50. Spring 事务、异步和循环依赖有什么关系?
  51. Spring 动态代理时是如何解决循环依赖的?为什么要使用三级缓存?
  52. "Stateless" of HTTP and "state transition" of rest
  53. [big data bibiji 20210128] use hive to calculate month on month and year on year
  54. [big data bibiji 20210125] Kafka will gradually abandon its dependence on zookeeper
  55. [big data beeps 20210124] someone asked me about Kafka leader election? I'm not in a panic
  56. [big data bibiji 20210123] don't ask, ask is Kafka highly reliable
  57. jQuery Gantt Package 在Visual Studio中创建一个新的ASP.NET项目
  58. What is the relationship between spring transactions, asynchrony, and circular dependencies?
  59. How to solve circular dependency in spring dynamic proxy? Why use level 3 caching?
  60. Unicode码的二进制转换(Java)