<> 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,
Python Garbage collection and memory leak hive Summary of processing methods for a large number of small files The difference between memory overflow and memory leak , Causes and Solutions Create data mysql Library process You don't know ——HarmonyOS stay Vue Use in Web WorkerSparkSQL Achieve partition overlay write msf Generate Trojan horse attack android mobile phone Linux Page replacement algorithm C Language implementation Django Personal blog building tutorial --- Time classified archiving