通过扩展点解决spring和dubbo版本不兼容下的属性不解析问题
通过扩展点解决spring和dubbo版本不兼容下的属性不解析问题
问题描述
spring+dubbo项目加入配置中心
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
异常信息如下:
Caused by: org.I0Itec.zkclient.exception.ZkException: Unable to connect to ${zookeeper.address}:9090
如下配置,使用了占位符${zookeeper.address}:
通过propertyPlaceholderConfigurer加载zookeeper.ip
同样的配置,在服务提供者端没有问题,在消费者端${zookeeper.address}没有被解析,导致连不上zookeeper。
于是尝试在原本运行正常的服务提供者端,加入dubbo:reference标签引用自己的服务,也就是同时也作为消费者端, 结果是${zookeeper.address}没有被解析。
也就是确定了问题出现的场景是:应用作为消费者时就会出现占位符未解析问题。
解决方法
通过自定义BeanFactoryPostProcessor,修改bean定义
spring.xml
<bean class="com.*.processor.ZookeeperConfigProcessor">
<property name="dubboZookeeperIds" value="preZookeeper" />
</bean>
Java
import com.alibaba.dubbo.config.RegistryConfig;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import java.util.List;
public class ZookeeperConfigProcessor implements BeanFactoryPostProcessor {
private static Logger logger= LoggerFactory.getLogger(ZookeeperConfigProcessor.class);
private String dubboZookeeperIds;
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0) throws BeansException {
if (StringUtils.isNotBlank(this.dubboZookeeperIds)){
String[] zkIds = this.dubboZookeeperIds.split(",");
for(String zkId:zkIds) {
BeanDefinition obj = arg0.getBeanDefinition(zkId);
Object singObj = arg0.getSingleton(zkId);
MutablePropertyValues pvs = obj.getPropertyValues();
List<PropertyValue> propertyValueList = pvs.getPropertyValueList();
for (PropertyValue pv : propertyValueList) {
logger.info("key:{} - value:{}" , pv.getName() , pv.getValue());
if ("address".equalsIgnoreCase(pv.getName())) {
if (singObj instanceof RegistryConfig) {
RegistryConfig registryConfig = (RegistryConfig) singObj;
registryConfig.setAddress(pv.getValue().toString());
}
}
}
}
}
}
public String getDubboZookeeperIds() {
return dubboZookeeperIds;
}
public void setDubboZookeeperIds(String dubboZookeeperIds) {
this.dubboZookeeperIds = dubboZookeeperIds;
}
}