千家信息网

dubbo中DubboApplicationContextInitializer的具体用法

发表于:2025-02-02 作者:千家信息网编辑
千家信息网最后更新 2025年02月02日,这篇文章主要介绍"dubbo中DubboApplicationContextInitializer的具体用法",在日常操作中,相信很多人在dubbo中DubboApplicationContextIn
千家信息网最后更新 2025年02月02日dubbo中DubboApplicationContextInitializer的具体用法

这篇文章主要介绍"dubbo中DubboApplicationContextInitializer的具体用法",在日常操作中,相信很多人在dubbo中DubboApplicationContextInitializer的具体用法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"dubbo中DubboApplicationContextInitializer的具体用法"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

DubboApplicationContextInitializer

dubbo-spring-boot-project-2.7.3/dubbo-spring-boot-compatible/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/context/DubboApplicationContextInitializer.java

public class DubboApplicationContextInitializer implements ApplicationContextInitializer, Ordered {    @Override    public void initialize(ConfigurableApplicationContext applicationContext) {        overrideBeanDefinitions(applicationContext);    }    private void overrideBeanDefinitions(ConfigurableApplicationContext applicationContext) {        applicationContext.addBeanFactoryPostProcessor(new OverrideBeanDefinitionRegistryPostProcessor());        applicationContext.addBeanFactoryPostProcessor(new DubboConfigBeanDefinitionConflictProcessor());    }    @Override    public int getOrder() {        return HIGHEST_PRECEDENCE;    }}
  • DubboApplicationContextInitializer实现了ApplicationContextInitializer, Ordered接口,initialize方法执行overrideBeanDefinitions,它往applicationContext添加了OverrideBeanDefinitionRegistryPostProcessor、DubboConfigBeanDefinitionConflictProcessor;getOrder返回的是HIGHEST_PRECEDENCE

OverrideBeanDefinitionRegistryPostProcessor

dubbo-spring-boot-project-2.7.3/dubbo-spring-boot-compatible/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/beans/factory/config/OverrideBeanDefinitionRegistryPostProcessor.java

public class OverrideBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {    @Override    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {        registerInfrastructureBean(registry, BEAN_NAME, DubboConfigBeanCustomizer.class);    }    @Override    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {    }}
  • OverrideBeanDefinitionRegistryPostProcessor实现了BeanDefinitionRegistryPostProcessor接口,其postProcessBeanDefinitionRegistry方法调用了BeanRegistrar.registerInfrastructureBean方法注册DubboConfigBeanCustomizer

BeanRegistrar

dubbo-2.7.3-sources.jar!/org/apache/dubbo/config/spring/util/BeanRegistrar.java

public class BeanRegistrar {    /**     * Register Infrastructure Bean     *     * @param beanDefinitionRegistry {@link BeanDefinitionRegistry}     * @param beanType               the type of bean     * @param beanName               the name of bean     */    public static void registerInfrastructureBean(BeanDefinitionRegistry beanDefinitionRegistry,                                                  String beanName,                                                  Class beanType) {        if (!beanDefinitionRegistry.containsBeanDefinition(beanName)) {            RootBeanDefinition beanDefinition = new RootBeanDefinition(beanType);            beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);            beanDefinitionRegistry.registerBeanDefinition(beanName, beanDefinition);        }    }}
  • registerInfrastructureBean在beanDefinitionRegistry没有该beanDefinition的情况下会注册BeanDefinition.ROLE_INFRASTRUCTURE的bean

DubboConfigBeanCustomizer

dubbo-spring-boot-project-2.7.3/dubbo-spring-boot-compatible/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/beans/factory/config/DubboConfigBeanCustomizer.java

@Deprecatedclass DubboConfigBeanCustomizer extends NamePropertyDefaultValueDubboConfigBeanCustomizer {    @Override    public void customize(String beanName, AbstractConfig dubboConfigBean) {        boolean valid = isValidPropertyName(dubboConfigBean, beanName);        if (valid) {            super.customize(beanName, dubboConfigBean);        }    }    private boolean isValidPropertyName(AbstractConfig dubboConfigBean, String propertyValue) {        boolean valid = true;        String propertyName = "name";        // AbstractConfig.checkName(String,String)        Method method = findMethod(AbstractConfig.class, "checkName", String.class, String.class);        try {            if (!method.isAccessible()) {                method.setAccessible(true);            }            if (BeanUtils.getPropertyDescriptor(dubboConfigBean.getClass(), propertyName) != null) {                invokeMethod(method, null, propertyName, propertyValue);            }        } catch (IllegalStateException e) {            valid = false;        }        return valid;    }}
  • DubboConfigBeanCustomizer继承了NamePropertyDefaultValueDubboConfigBeanCustomizer,其customize方法会先校验propertyName,在valid的情况下才会执行父类的customize方法

DubboConfigBeanDefinitionConflictProcessor

dubbo-spring-boot-project-2.7.3/dubbo-spring-boot-compatible/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/beans/factory/config/DubboConfigBeanDefinitionConflictProcessor.java

public class DubboConfigBeanDefinitionConflictProcessor implements BeanDefinitionRegistryPostProcessor, Ordered {    private final Logger logger = LoggerFactory.getLogger(getClass());    private BeanDefinitionRegistry registry;    private Environment environment;    @Override    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {        this.registry = registry;    }    @Override    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {        resolveUniqueApplicationConfigBean(registry, beanFactory);    }    /**     * Resolve the unique {@link ApplicationConfig} Bean     *     * @param registry    {@link BeanDefinitionRegistry} instance     * @param beanFactory {@link ConfigurableListableBeanFactory} instance     * @see EnableDubboConfig     */    private void resolveUniqueApplicationConfigBean(BeanDefinitionRegistry registry,                                                    ConfigurableListableBeanFactory beanFactory) {        this.environment = beanFactory.getBean(ENVIRONMENT_BEAN_NAME, Environment.class);        String[] beansNames = beanNamesForTypeIncludingAncestors(beanFactory, ApplicationConfig.class);        if (beansNames.length < 2) { // If the number of ApplicationConfig beans is less than two, return immediately.            return;        }        // Remove ApplicationConfig Beans that are configured by "dubbo.application.*"        Stream.of(beansNames)                .filter(this::isConfiguredApplicationConfigBeanName)                .forEach(registry::removeBeanDefinition);        beansNames = beanNamesForTypeIncludingAncestors(beanFactory, ApplicationConfig.class);        if (beansNames.length > 1) {            throw new IllegalStateException(String.format("There are more than one instances of %s, whose bean definitions : %s",                    ApplicationConfig.class.getSimpleName(),                    Stream.of(beansNames)                            .map(registry::getBeanDefinition)                            .collect(Collectors.toList()))            );        }    }    private boolean isConfiguredApplicationConfigBeanName(String beanName) {        boolean removed = BeanFactoryUtils.isGeneratedBeanName(beanName)                // Dubbo ApplicationConfig id as bean name                || Objects.equals(beanName, environment.getProperty("dubbo.application.id"));        if (removed) {            if (logger.isWarnEnabled()) {                logger.warn("The {} bean [ name : {} ] has been removed!", ApplicationConfig.class.getSimpleName(), beanName);            }        }        return removed;    }    @Override    public int getOrder() {        return LOWEST_PRECEDENCE;    }}
  • DubboConfigBeanDefinitionConflictProcessor实现了BeanDefinitionRegistryPostProcessor, Ordered接口;postProcessBeanFactory方法会执行resolveUniqueApplicationConfigBean,校验同一个beanDefinition是否会有多个实例,有的话会抛出IllegalStateException;getOrder返回的是LOWEST_PRECEDENCE

小结

DubboApplicationContextInitializer实现了ApplicationContextInitializer, Ordered接口,initialize方法执行overrideBeanDefinitions,它往applicationContext添加了OverrideBeanDefinitionRegistryPostProcessor、DubboConfigBeanDefinitionConflictProcessor;getOrder返回的是HIGHEST_PRECEDENCE

到此,关于"dubbo中DubboApplicationContextInitializer的具体用法"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

0