package com.xiaopeng.order.config; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.boot.context.properties.bind.Binder; import org.springframework.context.EnvironmentAware; import org.springframework.core.Ordered; import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; import java.util.Map; import java.util.Properties; /** * 修复 ShardingSphere 5.0.0 + Spring Boot 2.x 启动时 algorithm-expression 为 null 的问题。 */ @Component public class ShardingAlgorithmPropsFixer implements BeanFactoryPostProcessor, EnvironmentAware, Ordered { private static final String ALGO_PREFIX = "spring.shardingsphere.rules.sharding.sharding-algorithms"; private Environment environment; @Override public void setEnvironment(Environment environment) { this.environment = environment; } @Override public int getOrder() { return Ordered.LOWEST_PRECEDENCE; } @Override @SuppressWarnings("unchecked") public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { Map algorithms; try { algorithms = Binder.get(environment) .bind(ALGO_PREFIX, Map.class) .orElse(null); } catch (Exception e) { return; } if (algorithms == null) return; for (Map.Entry entry : algorithms.entrySet()) { String algoName = entry.getKey(); Object value = entry.getValue(); if (!(value instanceof Map)) continue; if (!beanFactory.containsBeanDefinition(algoName)) continue; Map algoConfig = (Map) value; Object propsObj = algoConfig.get("props"); if (!(propsObj instanceof Map)) continue; Map propsMap = (Map) propsObj; Properties props = new Properties(); for (Map.Entry pe : propsMap.entrySet()) { if (pe.getValue() != null) { props.put(pe.getKey(), pe.getValue().toString()); } } BeanDefinition bd = beanFactory.getBeanDefinition(algoName); bd.getPropertyValues().addPropertyValue("props", props); } } }