1. Spring properties配置项不能解析问题
本地部分配置文件迁到disconf,希望disconf的配置文件交由spring托管。这样的话,原有代码中引用配置的地方就不用变(还是用${key}的方式)。
在disconf上找到了配置方式:http://disconf.readthedocs.io/zh_CN/latest/tutorial-client/src/Tutorial5.html
结果启动后报异常,解析不了配置:Could not resolve placeholder
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'zookeeper.registry.address' in string value "${zookeeper.registry.address}" at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:174) at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:126) at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:204) at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:178) at org.springframework.context.support.PropertySourcesPlaceholderConfigurer$2.resolveStringValue(PropertySourcesPlaceholderConfigurer.java:175) at org.springframework.beans.factory.config.BeanDefinitionVisitor.resolveStringValue(BeanDefinitionVisitor.java:282) at org.springframework.beans.factory.config.BeanDefinitionVisitor.resolveValue(BeanDefinitionVisitor.java:209) at org.springframework.beans.factory.config.BeanDefinitionVisitor.visitPropertyValues(BeanDefinitionVisitor.java:141) at org.springframework.beans.factory.config.BeanDefinitionVisitor.visitBeanDefinition(BeanDefinitionVisitor.java:82) at org.springframework.beans.factory.config.PlaceholderConfigurerSupport.doProcessProperties(PlaceholderConfigurerSupport.java:208) ... 37 more
查看disconf的配置,断点,看到disconf交由spring托管的配置已经加载。
后面找到原因,是应用配置了多个 org.springframework.context.support.PropertySourcesPlaceholderConfigurer,导致了配置覆盖。
https://www.cnblogs.com/YingYue/p/5699962.html
保留的配置:
<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"> <property name="ignoreUnresolvablePlaceholders" value="true" /> <property name="locations"> <list> <value>classpath:xx.properties</value> </list> </property> </bean>
放disconf的配置:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!-- 使用托管方式的disconf配置(无代码侵入, 配置更改不会自动reload) --> <bean id="configproperties_no_reloadable_disconf" class="com.baidu.disconf.client.addons.properties.ReloadablePropertiesFactoryBean"> <property name="locations"> <list> <value>config.properties</value> </list> </property> </bean> <bean id="propertyConfigurerForProject1" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="ignoreResourceNotFound" value="true" /> <property name="ignoreUnresolvablePlaceholders" value="true" /> <property name="propertiesArray"> <list> <ref bean="configproperties_no_reloadable_disconf" /> </list> </property> </bean>
2. 引用的二方库中存在 HomeController,写死了根目录(/)重定向地址,导致首页地址不能自定义
homeController 是通过 component-scan 扫描出来的,自然想到通过 exclude-filter 来排除指定的 bean,然后自己再重新定义一个 bean 来解决。使用如下配置:
<context:component-scan base-package="com.kvn.xx" > <context:exclude-filter type="assignable" expression="com.xx.web.controller.system.HomeController"/> </context:component-scan>
结果发现二方库里面也配置了 component-scan ,会扫这个 HomeController,无耐只能想其他办法
断点在 AbstractApplicationContext#refresh(),在 bean 实例化之前 remove homeController 的 beanDefinition,这样就可以排除这个 bean 了。
最终发现可以扩展 BeanDefinitionRegistryPostProcessor 来实现:
@Component public class SfOpenHomeControllerFix implements BeanDefinitionRegistryPostProcessor { private static final String CONTROLLER_CLASS_PATH = "com.xxx.web.controller.system.HomeController"; private static final String CONTROLLER_BEAN_NAME = "homeController"; @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { if (Lists.newArrayList(registry.getBeanDefinitionNames()).contains(HOME_CONTROLLER_BEAN_NAME) && HOME_CONTROLLER_CLASS_PATH.equals(registry.getBeanDefinition(HOME_CONTROLLER_BEAN_NAME).getBeanClassName())) { // 移除二方库中的 homeController(里面写死了首页重定向) registry.removeBeanDefinition(HOME_CONTROLLER_BEAN_NAME); } } }
(实在不行,可以上大招:bytebuddy ^_^)