About the Dubbo extension point loading mechanism (1)

The most critical class in the Dubbo extension point loading mechanism is ExtensionLoader.java, which holds the full cache of extension point loading and the extension point's own cache. This chapter aims to dissect the structure and function of ExtensionLoader, the mechanism and others will be given in subsequent chapters.

Static properties: private static final ConcurrentMap<Class<?>, ExtensionLoader<?>> EXTENSION_LOADERS //Saves the key-value pair of the extension point interface and the extension point loader object

private static final ConcurrentMap<Class<?>, Object> EXTENSION_INSTANCES // Stores the class type implemented by the extension point and the instance of the extension point

Private property private final Class<?> type; //Assign value in the constructor to store the extension point interface class type

private final ExtensionFactory objectFactory; //Used to store the extension point implementation or nulll of ExtensionFactory (objectFactory = null when class is equal to ExtensionFactory.class, and objectFactory =AdaptiveExtensionFactory when class is not equal to ExtensionFactory.class)

private volatile Class<?> cachedAdaptiveClass //Adaptive extension point implementation class, there is only one for each extension point; when the extension point implementation class has the @Adaptive annotation or one is automatically generated

private final ConcurrentMap<String, Holder<Object>> cachedInstances //The full path name of the class corresponding to the key and the corresponding key in the spi configuration file

private String cachedDefaultName //The default value in the spi annotation

Method list: private constructor private ExtensionLoader(Class<?> type) //Assign the extension point interface type to the attribute type, there are two cases for the objectFactory value, see the private attribute objectFactory for details

public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) //Get the extension point loading class of the extension point from EXTENSION_LOADERS according to the extension point interface type; use the private constructor described above when it does not exist in EXTENSION_LOADERS Create a new ExtensionLoader object.

public T getAdaptiveExtension() //Execute the getExtensionClasses() method, traverse the spi file directory, and fill in each storage variable in the loadFile method; then obtain the adaptive extension point (Note: the extension point loader corresponding to each extension point type has only one automatic Adaptive extension point), create an extension point through the createAdaptiveExtensionClass() method when there is no adaptive extension point

private Class<?> createAdaptiveExtensionClass() //Create an adaptive extension point implementation according to the rules. By default, Javassit is used to dynamically compile and generate the bytecode of the adaptive extension class

private T createExtension(String name) //Determine whether EXTENSION_INSTANCES contains the corresponding implementation of the key value, if it does not exist, create an instance and store it in EXTENSION_INSTANCES for dependency injection through the injectExtension method. Next is the encapsulation of the decoration mode: if there is XXXWrapper in cachedWrapperClasses, the wrapper class of the extension point is instantiated through the constructor with the extension point interface as the parameter. For example, the wrapper classes ProtocolListenerWrapper and ProtocolFilterWrapper corresponding to the interface Protocol, that is, the implementation of each Protocol extension point needs to be wrapped by ProtocolListenerWrapper and ProtocolFilterWrapper and then returned to the wrapper class.

private T injectExtension(T instance)//The main function of this method is to implement dependency injection (IOC) for the properties of the extension point implementation class (public methods, standard set method writing, and only one input parameter), through objectFactory.getExtension The bean that obtains the attribute (the object object is directly obtained through SpringExtensionFactory) or the Adaptive class of the extension point corresponding to the attribute (obtained through SpiExtensionFactor), the object injected in the second method will only be passed in according to the url when it is actually called. The key gets the extension point implementation class that actually does the processing.

public List<T> getActivateExtension(URL url, String key) //Get the extension points that can be automatically activated, and get the automatic activation extension points by filtering the group and value in @Activate; for example, by using ExtensionLoader.getExtensionLoader (Filter.class).getActivateExtension(invoker.getUrl(), key, group); Get the automatic activation extension point implementation of the corresponding extension point com.alibaba.dubbo.rpc.Fitler.

public T getExtension(String name) //Search the extension point corresponding to the keyword by keyword; when the extension point implementation corresponding to the keyword does not exist in cachedInstances, use the createExtension() method to create the extension point implementation

private Class<?> getExtensionClass(String name) private Map<String, Class<?>> getExtensionClasses()//The function implemented by the above two methods is to read and obtain the extension point corresponding to the name from cachedNames; if it does not exist, pass The loadFile method scans the spi configuration file and loads it into the properties.

private T createAdaptiveExtension()//When the cachedAdaptiveClass property is empty, you need to use the createAdaptiveExtensionClass method to dynamically create an adaptive extension point implementation, and use javassist to complete the bytecode generation of this implementation.

private Map<String, Class<?>> loadExtensionClasses()//Use the loadFile method to load the extension point information into the global cache or the ExtensionLoader property

private void loadFile(Map<String, Class<?>> extensionClasses, String dir) //Load the spi file, parse the file content, traverse each keyword in the file and the full path of the extension point corresponding to the keyword one by one, according to the rules Put them in different attributes 1. Use the extension point implementation class of the Adaptive annotation to assign to cachedAdaptiveClass 2. When the extension point has a constructor that takes the extension point interface as a parameter, put the extension point implementation into cachedWrapperClasses to store the wrap of the upcoming extension point The class is put into cachedWrapperClasses 3. When it does not meet the conditions listed in 2, when the extension point implementation is annotated with @Activate, it is stored in cachedActivates, and then the extension point implementation is stored in cachedNames. Finally return cachedNames

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324991771&siteId=291194637