<> reflex

   The reflection mechanism is Java
A basic function provided by language , Giving programs introspection at run time (introspect) The ability of . Simply put, it's through reflection , Available at run time , Detecting and invoking properties and methods of objects .

Usage scenarios of reflection

1. Programming tools IDEA or Eclipse etc. , When you write code, you have code ( Property or method name ) Tips , It's because of reflection ;
2. Many well-known frameworks , In order to make the program more elegant and concise , Reflection is also used .

for example ,Spring Different classes can be loaded by configuration , Calling different methods , The code is shown below :
<bean id="person" class="com.spring.beans.Person" init-method="initPerson">
</bean>
for example ,MyBatis stay Mapper Using external classes Sql When building a query , The code is shown below :
@SelectProvider(type = PersonSql.class, method = "getListSql") List<Person>
getList(); class PersonSql { public String getListSql() { String sql = new
SQL() {{ SELECT("*"); FROM("person"); }}.toString(); return sql; } }
3. Database connection pool , Reflection is also used to call different types of database drivers , The code is shown below :
String url = "jdbc:mysql://127.0.0.1:3306/mydb"; String username = "root";
String password = "root"; Class.forName("com.mysql.jdbc.Driver"); Connection
connection = DriverManager.getConnection(url, username, password);
Basic use of reflection

Using reflection to call methods in a class , There are three cases :

* Calling static methods
* Calling public methods
* Calling private methods
Suppose you have an entity class MyReflect The above three methods are included , The code is as follows :
package com.interview.chapter4; class MyReflect { // Static method public static void
staticMd() { System.out.println("Static Method"); } // Public method public void
publicMd() { System.out.println("Public Method"); } // Private method private void
privateMd() { System.out.println("Private Method"); } }
① Reflection calls static methods
Class myClass = Class.forName("com.interview.chapter4.MyReflect"); Method
method = myClass.getMethod("staticMd"); method.invoke(myClass);
② Reflection calls public methods
Class myClass = Class.forName("com.interview.chapter4.MyReflect"); //
Create instance object ( amount to new ) Object instance = myClass.newInstance(); Method method2 =
myClass.getMethod("publicMd"); method2.invoke(instance);
③ Reflection calls private methods
Class myClass = Class.forName("com.interview.chapter4.MyReflect"); //
Create instance object ( amount to new ) Object object = myClass.newInstance(); Method method3 =
myClass.getDeclaredMethod("privateMd"); method3.setAccessible(true);
method3.invoke(object);
Reflection summary
   Reflection gets the calling class through Class.forName(), To obtain class instances through reflection newInstance(), amount to new A new object , The reflection acquisition method must pass the
getMethod(), After getting the class method, use invoke() Calling class methods . If the class method is private , You need to pass the setAccessible(true)
To modify the access restrictions for the method .

<> Dynamic proxy

   Dynamic proxy can be understood as , What you should have done yourself , It's left to someone else , This process is called dynamic proxy .

Usage scenarios of dynamic agents

   The well-known usage scenario of dynamic proxy is Spring Face to face programming in (AOP). for example , Dependency injection @Autowired And transaction annotations @Transactional
etc. , They are implemented by dynamic proxy . Dynamic proxies can also encapsulate some RPC call , A global interceptor can also be implemented by proxy .

The relationship between dynamic proxy and reflection

  JDK The dynamic proxy provided by native is implemented through reflection , But the implementation of dynamic proxy can also be ASM( A concise bytecode operation framework ),cglib( be based on
ASM) etc. , It's not limited to reflection .

JDK Native dynamic proxy and cglib Implementation of

1.JDK Native dynamic proxy
interface Animal { void eat(); } class Dog implements Animal { @Override
public void eat() { System.out.println("The dog is eating"); } } class Cat
implements Animal { @Override public void eat() { System.out.println("The cat
is eating"); } } // JDK proxy class class AnimalProxy implements InvocationHandler {
private Object target; // Proxy object public Object getInstance(Object target) {
this.target = target; // Get proxy object return
Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), this); } @Override public Object
invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(" Before calling "); Object result = method.invoke(target, args); // Method call
System.out.println(" After calling "); return result; } } public static void main(String[]
args) { // JDK Dynamic proxy call AnimalProxy proxy = new AnimalProxy(); Animal dogProxy =
(Animal) proxy.getInstance(new Dog()); dogProxy.eat(); }
be careful : JDK Proxy Only classes that implement interfaces can be proxied ( even if it is extends Inherited classes are also not surrogate ).

2.cglib Dynamic proxy

   If you use it cglib Implementation to add pair cglib References to , If it is maven Project , Add the following code directly :
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId>
<version>3.2.12</version> </dependency>
cglib The concrete realization of , Please refer to the code below :
class Panda { public void eat() { System.out.println("The panda is eating"); }
} class CglibProxy implements MethodInterceptor { private Object target; //
Proxy object public Object getInstance(Object target) { this.target = target; Enhancer
enhancer = new Enhancer(); // Set parent class as instance class
enhancer.setSuperclass(this.target.getClass()); // Callback method
enhancer.setCallback(this); // Create proxy object return enhancer.create(); } public Object
intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy)
throws Throwable { System.out.println(" Before calling "); Object result =
methodProxy.invokeSuper(o, objects); // Execute method call System.out.println(" After calling ");
return result; } } public static void main(String[] args) { // cglib Dynamic proxy call
CglibProxy proxy = new CglibProxy(); Panda panda = (Panda)proxy.getInstance(new
Panda()); panda.eat(); }
Results of the above procedures :
Before calling The panda is eating After calling
   From the above code can know ,cglib By implementing the MethodInterceptor Interface intercept method , call invokeSuper
Dynamic proxy . It can be used to proxy ordinary classes dynamically , It doesn't need to be like JDK Agent like that , It needs to be done through the interface , It is worth mentioning that Spring The dynamic proxy of the cglib
Realized .

be careful :cglib The underlying layer implements dynamic proxy through subclass inheritance , Therefore, the proxy class cannot be the final class (final), Otherwise, it will report an error
java.lang.IllegalArgumentException: Cannot subclass final class xxx.

<> Written interview questions

1. What problem does dynamic proxy solve ?

answer : First of all, it is a proxy mechanism , A proxy can be seen as a wrapper around the call target , In this way, our call to the object code does not happen directly , It's done through an agent , The agent can decouple the caller from the implementer . For example
RPC call , Through agency , Can provide a more friendly interface ; You can also use an agent , Be a global interceptor .

2. What is the relationship between dynamic proxy and reflection ?

answer : Reflection can be used to implement dynamic proxies , But there are other ways to implement dynamic proxy , such as ASM( A concise bytecode operation framework ),cglib etc .

3. The following description is incorrect ?

A:cglib Higher performance of
B:Spring In the cglib To implement dynamic proxy
C:Spring In the JDK Native dynamic proxy
D:JDK Better native dynamic proxy performance

answer :D

Topic analysis :Spring There are two ways to implement dynamic proxy :cglib and JDK Native dynamic proxy .

4. Please complete the code below ?
class MyReflect { // Private method private void privateMd() {
System.out.println("Private Method"); } } class ReflectTest { public static
void main(String[] args) throws ClassNotFoundException, NoSuchMethodException,
InvocationTargetException, IllegalAccessException, InstantiationException {
Class myClass = Class.forName("MyReflect"); Object object =
myClass.newInstance(); // Add this line of code method.setAccessible(true);
method.invoke(object); } }
answer :Method method = myClass.getDeclaredMethod("privateMd");

Topic analysis : This question is mainly about the acquisition of private methods , Private methods are not acquired through getMethod() mode , But through getDeclaredMethod() Acquired .

5.cglib Can represent any class, right ? Why? ?

answer : Not exactly , because cglib Only normal classes that can have subclasses can be proxied , For the final class like (final),cglib Dynamic proxy cannot be implemented , because cglib
The underlying layer of proxy is to implement dynamic proxy by inheriting the subclass of proxy class , So it can't be inherited. Classes can't be used cglib.

6.JDK Native dynamic proxy and cglib What's the difference? ?

answer :JDK Native dynamic proxy and cglib The difference is as follows :

* JDK Native dynamic proxy is implemented based on interface , There is no need to add any dependencies , Smooth support JDK Version upgrade ;
* cglib There is no need to implement the interface , You can directly proxy a common class , Dependency package needs to be added , Higher performance .
7. Why? JDK The native dynamic proxy must be completed through the interface ?

answer : This is because JDK Reasons for native design , Implementation of dynamic proxy newProxyInstance() The source code is as follows :
/** * ...... * @param loader the class loader to define the proxy class *
@param interfaces the list of interfaces for the proxy class to implement *
...... */ @CallerSensitive public static Object newProxyInstance(ClassLoader
loader, Class<?>[] interfaces, InvocationHandler h) throws
IllegalArgumentException { // Omit other codes
You can see , Declaration of the first two parameters :

* loader: Class loader , that is target.getClass().getClassLoader()
* interfaces: Interface implementation list of interface proxy class
therefore , To use JDK Native dynamics can only be accomplished by implementing interfaces .

Technology
©2019-2020 Toolsou All rights reserved,
C Review of basic language knowledge Go Language learning notes (GUI programming )Java Misunderstanding —— Method overloading is a manifestation of polymorphism ? How to achieve low cost and high stability for cloud native applications ?elementui Shuttle box el-transfer Display list content text too long C/C++ Memory model Element-Ui assembly Message Message prompt , alert Popup C# Making a simplified version of calculator Python In pycharm editor Interface style modification Tiktok refresh progress bar ( Two little balls turn ), The code is simple