当前位置:网站首页>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
边栏推荐
- About vscode, "code unreachable" will be displayed when calling sendline series functions with pwntools“
- C learning notes
- Course learning accumulation ppt
- Ros2 - Service Service (IX)
- iNFTnews | 喝茶送虚拟股票?浅析奈雪的茶“发币”
- Spinningup drawing curve
- Executealways of unity is replacing executeineditmode
- [framework] multi learner
- ModuleNotFoundError: No module named ‘picamera‘
- [node] differences among NPM, yarn and pnpm
猜你喜欢
1290_ Implementation analysis of prvtaskistasksuspended() interface in FreeRTOS
睿智的目标检测59——Pytorch Focal loss详解与在YoloV4当中的实现
The problem of configuring opencv in qt5.13.2 is solved in detail
Ros2 - common command line (IV)
IPage能正常显示数据,但是total一直等于0
Steps and FAQs of connecting windows Navicat to Alibaba cloud server MySQL
U-Boot初始化及工作流程分析
Ros2 - install ros2 (III)
数学分析_笔记_第8章:重积分
Machine learning Seaborn visualization
随机推荐
Anaconda navigator click open no response, can not start error prompt attributeerror: 'STR' object has no attribute 'get‘
2022.06.27_ One question per day
【软件测试】06 -- 软件测试的基本流程
小米笔试真题一
[vscode] recommended plug-ins
SOC_SD_DATA_FSM
testing framework
[nvidia] CUDA_ VISIBLE_ DEVICES
Reading literature sorting 20220104
Machine learning Seaborn visualization
Oracle code use
Ros2 - first acquaintance with ros2 (I)
GPIO port bit based on Cortex-M3 and M4 with operation macro definition (can be used for bus input and output, STM32, aducm4050, etc.)
[vscode] search using regular expressions
[software testing] 03 -- overview of software testing
M2DGR 多源多场景 地面机器人SLAM数据集
What if the DataGrid cannot see the table after connecting to the database
ROS2——功能包(六)
Powermanagerservice (I) - initialization
氢氧化钠是什么?