• Spring踩坑记录


    1. Spring properties配置项不能解析问题

    本地部分配置文件迁到disconf,希望disconf的配置文件交由spring托管。这样的话,原有代码中引用配置的地方就不用变(还是用${key}的方式)。

    在disconf上找到了配置方式:http://disconf.readthedocs.io/zh_CN/latest/tutorial-client/src/Tutorial5.html

    结果启动后报异常,解析不了配置:Could not resolve placeholder

    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
    View Code

    查看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的配置:

    <!-- 使用托管方式的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>
    View Code

    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 ^_^)

  • 相关阅读:
    【BZOJ3261】— 最大异或和(可持久化0/1Trie)
    【ZJOI2007】—捉迷藏(动态点分治)
    【HNOI2010】-城市建设(动态最小生成树)
    【BOI2007】Mokia 摩基亚
    【BZOJ 3262】-陌上花开(CDQ分治+树状数组)
    Win64 驱动内核编程-24.64位驱动里内嵌汇编
    Win64 驱动内核编程-23.Ring0 InLineHook 和UnHook
    Win64 驱动内核编程-23.Ring0 InLineHook 和UnHook
    Win64 驱动内核编程-22.SHADOW SSDT HOOK(宋孖健)
    Win64 驱动内核编程-22.SHADOW SSDT HOOK(宋孖健)
  • 原文地址:https://www.cnblogs.com/kevin-yuan/p/7867224.html
Copyright © 2020-2023  润新知