In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >
Share
Shulou(Shulou.com)05/31 Report--
This article mainly introduces "how to achieve the extension mechanism in Dubbo". In the daily operation, I believe that many people have doubts about how to achieve the extension mechanism in Dubbo. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful to answer the doubts about "how to achieve the extension mechanism in Dubbo". Next, please follow the editor to study!
SPI
Dubbo uses SPI (Service Provider Interface) to implement the extension mechanism.
You must all be familiar with this SPI. You came across it when you were writing a big database assignment in college. You need to use java.sql.Driver to access the database.
There are a variety of databases on the market, and each database vendor has its own implementation, so it is necessary to customize an interface so that we can program for the interface.
The specific implementation can be loaded through configuration, and JDK SPI will come in handy at this time.
In fact, it is not magical at all, that is, to agree on a place to go to that place to find the implementation class when loading.
To agree on a place to put it bluntly, there is a directory written in the code, which is META-INF/services/.
Then create a file in this directory and name it with the fully qualified name of the interface. The content of the file is the fully qualified name of the implementation class.
If you want to implement the class, come here according to the interface name, and then instantiate it.
It's pretty simple, this is JDK SPI, but it doesn't meet the needs of Dubbo.
Because Dubbo also strips out some of its own implementations as extensions, and these implementations are still a bit many, and do not need to use all of them.
If you use JDK SPI, you will load all the classes in the configuration file, which leads to a waste of resources. When using it, you still need to traverse the past to find the corresponding implementation.
So Dubbo implements a SPI of Dubbo on the basis of JDK SPI, which can load the implementation class on demand according to the specified name. For example, there are so many implementation classes in Cluster.
The appointed place has been changed. There are three catalogs altogether.
META-INF/dubbo/internal/: here is the SPI configuration file for internal use in Dubbo.
META-INF/dubbo/: this is where the user-defined SPI configuration file is stored.
META-INF/services/: is compatible with JDK SPI
Then the contents of the file are in key=value form, so that the corresponding implementation class can be found according to key.
Then you can configure the default key on the annotation to select the default implementation class, for example, the default implementation of Cluster is failover.
You can also select the implementation class through the URL parameter.
And if the JDK SPI extension point fails to load, you can't even get the name of the extension point, and you don't know what went wrong when you reported the error.
Dubbo SPI, on the other hand, does not eat mistakes, and also provides automatic injection and AOP of extension points.
After getting a general understanding of Dubbo SPI, let's take a closer look at the implementation details.
Dubbo SPI implementation details
The core implementation of Dubbo SPI is in ExtensionLoader, which is responsible for the loading of extension points and lifecycle maintenance, similar to JDK SPI's ServiceLoader.
Here is a little tip to look at the source code first.
All open source frameworks will have unit tests, and unit tests will have the various functional implementations we want when looking at the source code, so we can know the division of some functions from the unit testing, and then the breakpoint debugging will go deeper and deeper.
For example, ExtensionLoader in today's article, which is in the dubbo-common module, let's go into test to see how its test case is written.
Of course, in addition to looking through the folder, you can also search directly with the file name.
Found it is easy to do, the data are built, find the method you want to debug, breakpoint set, arrow point, this is not happy?
All right, after sharing the tips, let's go back to ExtensionLoader. Let's simply take a look at the implementation with the data from the Dubbo unit test.
There is a class called SimpleExt that has three implementations, and the default implementation is impl1.
If you look at the contents of the SPI configuration file, you can see that some spaces have been deliberately written in the configuration file for testing.
Then now if you want to find the implementation of impl2, you can call it with the following code.
SimpleExt ext = ExtensionLoader .getExtensionLoader (SimpleExt.class) .getExtension ("impl2")
An extension interface has an ExtensionLoader, find the corresponding ExtensionLoader, and then load the implementation class with the corresponding name.
There will be source code next, but it doesn't matter, it's still very simple, you have to go through it if you want to go deep into the source code.
You can see that the getExtensionLoader is static, and the logic is simple: find the ExtensionLoader corresponding to the interface from the cache, and create a new return if you can't find it.
Now that we have ExtensionLoader, let's look at the logic of getExtension to see how the corresponding implementation class is found through the extension point name.
You can see that there is another cache operation, and the logic is very simple. First, go to the cache to find an instance, and if not, create an instance.
For details, double check locks are used, and then holder is used to ensure visibility and prevent instruction rearrangement. You should see the holder construction on the comments, the combination of volatile and double check locks, so I won't go any further here.
Let's take a look at createExtension, which is about to create an extension point, the code is a bit long, but I have made comments accordingly, including green comments.
The logic is still very simple, the detailed code is not specifically shown, let me dictate it first.
Go to three directories to find the corresponding files through the interface class name.
Parsing the contents of the file generates a class object, which is then cached in cachedClasses.
Then go to cachedClasses through name to find the corresponding class object.
Cache the EXTENSION_INSTANCES to see if it has been instantiated.
If not, instantiate it, then call injectExtension to implement automatic injection.
Then the wrapper is implemented through cachedWrapperClasses, and the final wrapper class is returned.
It doesn't matter if there are a few points that are not clear. Let's go on with the analysis. We'll probably know what to do first, and then we'll see how it's done.
LoadDirectory in the source code is to go to the directory to find files, and then parse, and eventually call loadClass, this method is very critical, we analyze in detail, in order to facilitate viewing, deleted some code.
Let's skip the adaptation first, as long as we know that it is recorded here.
Then the AOP-related cachedWrapperClasses mentioned above is recorded here. What if it is judged to be a wrapper class?
Simple, rude but effective, as long as the class with the current class as the constructor parameter is the wrapper class, it's a bit of a mouthful, and you'll understand it by reading it a few times.
Now let's go back and look at this code, Dubbo's AOP.
Record all the wrapper classes corresponding to the extension class in cachedWrapperClasses, and then wrap the extension class layer by layer when instantiating the extension class, and the final return is the wrapper class.
Why is this AOP? Because it is tantamount to cutting some logic into the extension implementation class.
In fact, it is to move the common logic of the extension object to the wrapper class, and the example of unit testing is clear.
You can see from the figure that there are two extension implementation classes and two wrapper classes. The specific logic is ignored and is not the key point. The configuration file is as follows:
Then take a look at the running results of the unit test, and you can see that the final return is actually an Ext5Wrapper1 object, and it also wraps a wrapper2 object.
So the call chain of the echo method is: Ext5Wrapper1-> Ext5Wrapper2- > Ext5impl1
It also has the effect of AOP.
Next let's take a look at how injectExtension implements the automatic injection of Dubbo.
At this point, the study on "how to implement the extension mechanism of Dubbo" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.