当前位置:网站首页>And let's play dynamic proxy (extreme depth version)
And let's play dynamic proxy (extreme depth version)
2022-07-05 07:16:00 【I am the king of X】
Disgusting things take time to make them more disgusting 🧎*️ ----xmonster
List of articles
The opening
You can see it. 《 Zen of design pattern 》( The first 2 edition ) Understanding of agency mode in , He used “ Play strange games ” Example , I think it's very vivid , Understand very thoroughly ! If you are not very clear about the agency mode , Then dynamic proxy is naturally more difficult for you to understand , Don't do useless work , First, fill the foundation ( Don't forget to make it up and come back ); If you already know , Then go on !
Let's have a picture , It doesn't make any sense , Just to wake up , This is the flow chart of the book above
This blog post is long , Please be patient after reading
🧡🧡🧡🧡🧡
Go through Baidu Encyclopedia
Dynamic proxy class
Java The dynamic proxy class is located in Java.lang.reflect It's a bag , Here and Java The reflection of is closely related , If you don't understand Java Reflection of , It is difficult to understand dynamic proxy , Here is an article about Java Summary of the basic understanding of reflection , Mainly refer to Baidu Encyclopedia : Big talk Java The reflex mechanism
Generally, the following two categories are involved :
One 、Interface InvocationHandler
: There is only one method defined in this interface Object:invoke(Object obj,Method method,Object[] args). In actual use , The first parameter obj Generally speaking, it means proxy class
,method yes The method of being represented
,args For the parameter array of this method . This abstract method is implemented dynamically in the proxy class .
Two 、Proxy
: This class is called dynamic proxy class, which mainly includes the following contents :
Protected Proxy(InvocationHandler h): Constructors , Estimated for internal h assignment .
Static Class getProxyClass (ClassLoader loader,Class[] interfaces): Get a proxy class , among loader It's a class loader ,interfaces Is an array of all interfaces owned by a real class .( Create a proxy for an interface ) Focus on the following methods :
Static Object newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h): return An instance of the proxy class
, The returned proxy class can be used as the proxied class ( You can use the proxied class in Subject Methods declared in the interface ).
So-called Dynamic Proxy It's like this class: It's generated at run time class, When generating it You must provide a set interface Give it
, And then the class To claim that it has achieved these interface
. Of course you can put the class As an example of these interface Use any one of them . Of course! , This Dynamic Proxy It's really just a Proxy, It doesn't do substantive work for you , When generating its instance You have to provide a handler
, It takes over the actual work .
Agency mechanism and characteristics ( Use steps )
By implementing InvocationHandler Interface to create its own call handler ;
By providing Proxy class Appoint ClassLoader object
and A group of interface
To create a dynamic proxy class ;
Get the constructor of the dynamic proxy class through the reflection mechanism , Its only parameter type is the call handler interface type
;
Creating a dynamic proxy class instance through a constructor , The call handler object is passed in as a parameter during construction .
It doesn't understand , No problem , Now take your time
The following code completes the corresponding dynamic proxy implementation in this order
Tool class code of dynamic proxy
The following code comments are my personal understanding , Somewhat chaotic , But it's very nice, You can also skip directly ~
package com.xmonster.demo01;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// Later, we will use this class to automatically generate proxy classes !
public class ProxyInvocationHandler implements InvocationHandler {
// Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
// new Class<?>[] { Foo.class },
// handler);
// The interface being proxied
// 1、 Proxy an interface Who is this interface , Is the real object ; The real object will implement that interface , We'll finish acting for it
private Object target;
public void setTarget(Object target) {
this.target = target;
}
// Generate the proxy class
public Object getProxy(){
// getClassLoader() Class loader : It is responsible for loading bytecode files into memory , establish Class object
// target.getClass().getClassLoader() adopt target From the example Loader() Information
// target.getClass().getInterfaces() Get the corresponding interfaces Information ( Reflection )
// System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
// target.getClass().getClassLoader()
/* target.getClass() Get its class object * getClassLoader(): Every Class Objects have a method , You can get it ClassLoader * target.getClass().getClassLoader(): Get the class and get the class loader of this class * * * * */
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
this);
// newProxyInstance: Returns an instance of the proxy class for the specified interface , This interface dispatches method calls to the specified call handler .
// loader - Class loader to define the proxy class
//interfaces - List of interfaces implemented by proxy class
//h - Call handler for scheduling method calls
}
// Handling agent instances , And return the result
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// The proxy is an interface
// The essence of dynamic proxy , Is to use reflection mechanism to achieve
setHost();
Object invoke = method.invoke(target, args);
return invoke;
}
}
This code is believed to be familiar to experienced old dogs , This code is written by watching the video of crazy God , So his example is also used , Examples of landlords and intermediaries , Now let's explore the meaning and use of the above code
Let's start with a test class
package com.xmonster.demo01;
public class Client {
public static void main(String[] args) {
// Real object
UserService userService = new UserServiceImpl();
// Proxy object
ProxyInvocationHandler pih = new ProxyInvocationHandler();
// Generate proxy roles
pih.setTarget(userService); // Set the object to be represented
// Dynamic generation 、 Get the proxy class , Get proxy class object
// Notice the cast here
UserService proxy =(UserService) pih.getProxy();
// Object proxy = pih.getProxy();
// Just call the method of the responding agent
proxy.query();
}
}
analysis
Back to what we said above , Both the proxy class and the proxied class implement one “ Interface ”, Only the proxy class passes a parameter ( Pass the proxied class ), Then help the proxy class do things , So the point is “ Interface ”
( Proxies and actual objects generally have the same interface )
That's why
UserService proxy =(UserService) pih.getProxy();
Here is the reason for the strong turn
It's not like adapters and decorators , Because agents are generally Do not change the interface
Realization way
Implementation methods generally include 2 Kind of , One is Java SDK, One is cglib
Here's about newProxyInstance、InvocationHandler The examples and parameters are understood in this blog :
And play the little chestnut of dynamic proxy
Because we also need to combine this example to play , So let's first look at the above example , Contrast understanding
take SimpleInvocationHandler The main function of is implemented in another way :
Class<?> proxyClass = Proxy.getProxyClass(IService.class.getClassLoader(),
new Class<?>[] {
IService.class});
Constructor<?> ctor = proxyClass.getConstructor(new Class<?>[] {
InvocationHandler.class});
InvocationHandler handle = new SimpleInvocationHandler(realService);
IService proxyService = (IService) ctor.newInstance(handle);
proxyService.sayHello();
Understand the steps :
- adopt Proxy.getProxyClass That created the proxy class “ Definition ”, Class definitions will be cached ;
- Get the construction method of the class , One of the construction methods is InvocationHandler Parameters of type
- establish InvocationHandler object , The proxy object is created
Proxy.getProxyClass
The source of this method :
public static Class<?> getProxyClass(ClassLoader loader,
Class<?>... interfaces)
throws IllegalArgumentException
{
Class<?> caller = System.getSecurityManager() == null
? null
: Reflection.getCallerClass();
return getProxyConstructor(caller, loader, interfaces)
.getDeclaringClass();
}
You can see that this method requires two parameters , One is ClassLoader, The other is the interface array
Given the class loader and interface array of proxy classes java.lang.Class object . The proxy class will be defined by the specified class loader , And will implement all provided interfaces . If any given interface is not public , Then the proxy class will be non-public . If the class loader has defined a proxy class with the same interface substitution , Then the existing proxy class will be returned ; otherwise , The proxy classes of these interfaces will be dynamically generated and defined by the class loader .
This method will dynamically generate a class , The class name is $Proxy start , Then it will be followed by some numbers
Parameters
loader - Class loader to define the proxy class
interfaces - List of interfaces of proxy classes to be implemented
result
Define and implement the proxy class of the specified interface in the specified class loader
Given by this method
Class loader
andInterface array proxy class java.lang.Class object
. The proxy class will be defined by the specified class loader ,And will implement all provided interfaces
. If any given interface is not public , Then the proxy class will be non-public . If the class loader has defined a proxy class with the same interface substitution , Then the existing proxy class will be returned ; otherwise , The proxy classes of these interfaces will be dynamically generated and defined by the class loader .
$Proxy0
Here's the analysis $Proxy0 The source code will be particularly clear ( The code is long , It's not released here , You can baidu , They all look the same , It mainly depends on its construction method and structure )
$Proxy0 The parent class is Proxy, And it has a construction method , Accept one InvocationHandler Parameters of type , Save as instance variables h,h Defined in the parent class Proxy Kind of ,
It implements the interface IService
, For each method , Will be called InvocationHandler Of invoke Method , about Object Many methods in , Also transferred to InvocationHandler
The class definition itself has nothing to do with the object being represented , And InvocationHandler It doesn't matter whether it's a concrete implementation of , It is mainly related to interface array , Given this interface array , It will dynamically create the implementation code of each interface , Implementation is to forward to InvocationHandler, With the proxied object and its call by InvocationHandler Implementation management
The next step is to get the constructor , Create proxy object !
getConstructor
@CallerSensitive
public Constructor<T> getConstructor(Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException
{
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), true);
}
return getReflectionFactory().copyConstructor(
getConstructor0(parameterTypes, Member.PUBLIC));
}
- getConstructor Method returns a Constructor object , This object reflects Constructor The specified public class function of the class represented by the object . parameterTypes Parameters are an array of class objects that identify the formal parameter type of the constructor in the order of declaration . If such an object represents an inner class declared in a non static context , Then the formal parameter type will explicitly surround the instance as the first parameter .
newInstance
public T newInstance(Object ... initargs)
throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException
- Use this Constructor Object represents the constructor , Creates and initializes a new instance of the constructor's declaration class with the specified initialization parameters . Individual parameters are automatically unpacked to match the original formal parameters , Both the original reference parameters and the reference parameters need to be converted into method calls .
- If the constructor completes normally , Then return the newly created and initialized instance .
- Parameters initargs - An array of objects to be passed as arguments to constructor calls ; The value of the original type is wrapped in a wrapper object of the appropriate type ( for example float Medium float )
result
A new object created by calling the constructor represented by this object
In this way, the whole process is basically over
边栏推荐
- Powermanagerservice (I) - initialization
- Logical structure and physical structure
- Executealways of unity is replacing executeineditmode
- Course learning accumulation ppt
- M2DGR 多源多场景 地面机器人SLAM数据集
- The difference between NPM install -g/-save/-save-dev
- Implementation of one-dimensional convolutional neural network CNN based on FPGA (VIII) implementation of activation layer
- 苏打粉是什么?
- M2dgr slam data set of multi-source and multi scene ground robot
- 【obs】x264编码:“buffer_size“
猜你喜欢
Powermanagerservice (I) - initialization
SOC_SD_CMD_FSM
ROS2——配置开发环境(五)
What if the DataGrid cannot see the table after connecting to the database
Docker installs MySQL and uses Navicat to connect
Pytorch has been installed in anaconda, and pycharm normally runs code, but vs code displays no module named 'torch‘
window navicat连接阿里云服务器mysql步骤及常见问题
1290_ Implementation analysis of prvtaskistasksuspended() interface in FreeRTOS
1290_FreeRTOS中prvTaskIsTaskSuspended()接口实现分析
Intelligent target detection 59 -- detailed explanation of pytoch focal loss and its implementation in yolov4
随机推荐
C#学习笔记
[node] differences among NPM, yarn and pnpm
[node] NVM version management tool
Implementation of one-dimensional convolutional neural network CNN based on FPGA (VIII) implementation of activation layer
ORACLE CREATE SEQUENCE,ALTER SEQUENCE,DROP SEQUENCE
ImportError: No module named ‘Tkinter‘
[vscode] recommended plug-ins
2022.06.27_ One question per day
ROS2——初识ROS2(一)
SD_CMD_SEND_SHIFT_REGISTER
[software testing] 05 -- principles of software testing
Tshydro tool
Xiaomi written test real question 1
Brief description of inux camera (Mipi interface)
并发编程 — 如何中断/停止一个运行中的线程?
PostMessage communication
Concurrent programming - deadlock troubleshooting and handling
逻辑结构与物理结构
基于Cortex-M3、M4的GPIO口位带操作宏定义(可总线输入输出,可用于STM32、ADuCM4050等)
网易To B,柔外刚中