What to do

After looking at the Dubbo website, we found dubbo direct connection, which simplifies the process of developing our environment and eliminates the need to start a registry. So I wanted to apply it to my own projects. However, all kinds of websites have seen many cases of dubbo direct connection, which are basically consistent with the official website. The way of specifying the URL for each service is not suitable for our own project. I want all services to use dubbo://127.0.0.1:20880 URL

Dubbo version: 2.7.8

Source code process analysis

Here we create a Spring-managed Controller with only one property identified by the Reference annotation, and then look at the power injection flow: Populate the Controller class by scanning the properties identified by the Reference annotation and starting to generate proxy objects

org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor#doGetInjectedBean
// Perform a series of parses, but no more detailsCall referenceBean. The get () implementation org. Apache. Dubbo. Config. ReferenceConfig# init org.apache.dubbo.config.ReferenceConfig#checkAndUpdateSubConfigs org.apache.dubbo.config.ReferenceConfigBase#resolveFile// This parses the URL configured in the dubbo file

org.apache.dubbo.config.ReferenceConfig#postProcessConfig // This is an extensibility point
// Method source code
private void postProcessConfig(a) {
        List<ConfigPostProcessor> configPostProcessors = ExtensionLoader.getExtensionLoader(ConfigPostProcessor.class)
                .getActivateExtension(URL.valueOf("configPostProcessor://"), (String[]) null);
        configPostProcessors.forEach(component -> component.postProcessReferConfig(this));
} 
Copy the code

The ConfigPostProcessor interface is an spi extension. How to extend this interface is not described in the official website. Can we copy other SPI extensions and debug our own

The ConfigPostProcessor interface is used to set the ReferenceConfig attribute, which is then added to a map. The map is then used to create the proxy class (also in the init method, to create an assignment to ref, Referencebean.get () returns ref.

The initial ideas: 1. Use filter to switch the URL in Invoker before each invocation, because there are too many layers and it is not easy to set. 2. Use spring extension, BPP and other methods to judge that the attributes in them are not the attributes of Reference and modify them, the same as above

The actual coding

Spi extension based on the ConfigPostProcessor interface

@Activate(group = {CommonConstants.CONSUMER})
public class DubboRedirectConfigPostProcessor implements ConfigPostProcessor {` ` `public static final String DUBBO_URL = "Dubbo: / / 127.0.0.1:20880";

private List<String> activeProfiles;

/ * * *. Org apache. Dubbo. Config. ReferenceConfig# postProcessConfig () call *@param referenceConfig
 */
public void postProcessReferConfig(ReferenceConfig referenceConfig) {
    if(! activeProfiles.contains("dev")) {
        Use direct connection only in the development environment
        return;
    }

    // Dubbo url can be set according to the package name
    System.out.println("Dubbo extension" + referenceConfig.getServiceMetadata().getServiceType());
    referenceConfig.setUrl(DUBBO_URL);
}

@Override
// Dubbo instantiates this class and executes it by taking the Environment object from the Spring context object
public void setEnvironment(Environment environment) {
    this.activeProfiles = Arrays.asList(environment.getActiveProfiles()); }}Copy the code

In the meta-inf. Create com under dubbo. Alibaba. Dubbo. Config. ConfigPostProcessor file, Write to you the full path of the implementation class dubboDirect = com. Config. DubboDirectConfigPostProcessor

If you have no problems with the above steps, configPostProcessors has successfully added to your implementation class, and more extensions can be implemented in the postProcessReferConfig method

Check =false dubo.registry. Address =N/A in the application. Properties file

This parameter is valid only for dev

DubboRedirectConfigPostProcessor EnvironmentAware interface, whether getActiveProfiles environment need to perform postProcessReferConfig method is ok,

In dubbo such org. Apache. Dubbo. Config. Spring. The extension. SpringExtensionFactory, which contains the spring context object, source code after the instantiation, analytical methods, After resolving to the standard named setEnvironment method, execute the method by taking the Environment object as a parameter from the context object

org.apache.dubbo.common.extension.ExtensionLoader#getExtension(java.lang.String, boolean)
org.apache.dubbo.common.extension.ExtensionLoader#createExtension


 try {
                    String property = getSetterProperty(method);
                    // Get the Environment from the Spring context
                    Object object = objectFactory.getExtension(pt, property);
                    if(object ! =null) {
                    	// Execute the set methodmethod.invoke(instance, object); }}catch (Exception e) {
                    logger.error("Failed to inject via method " + method.getName()
                            + " of interface " + type.getName() + ":" + e.getMessage(), e);
                }
Copy the code

Git address

Github.com/zhaokun-12/…