zoukankan      html  css  js  c++  java
  • 它们的定义PropertyPlaceHolder无法完成更换任务

     Spring默认PropertyPlaceholderConfigurer只能加载properties格风格简介,现在,我们需要能够从类的完整支持允许似hadoop格风格xml配置文件读取配置信息,并更换相关bean占位符,对其进行了扩展,详细扩展例如以下:

    public class CustomPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
        private Resource[] locations;
    
        public void loadProperties(Properties props) throws IOException {
            if (this.locations != null) {
                PropertiesPersister propertiesPersister = new DefaultPropertiesPersister();
                for (int i = 0; i < this.locations.length; i++) {
                    Resource location = this.locations[i];
                    if (logger.isInfoEnabled()) {
                        logger.info("Loading properties file from " + location);
                    }
                    InputStream is = null;
                    try {
                        is = location.getInputStream();
                        propertiesPersister.load(props, is);
    
                        Configuration conf = SquirrelConfiguration.create();
                        Map<String, String> map = conf.listAllConfEntry();  // 从squirrel-site.xml中读取配置信息
                        for (Map.Entry<String, String> entry : map.entrySet()) {
                            props.put(entry.getKey(), entry.getValue());
                        }
                    } finally {
                        if (is != null) is.close();
                    }
                }
            }
        }
    
        public void setLocations(Resource[] locations) {
            super.setLocations(locations);
            this.locations = locations;
        }
    
    }




    可是执行却一直报错,${jdbc_driver_name}没有被替换。通过查询发现。原来是在spring里使用org.mybatis.spring.mapper.MapperScannerConfigurer 进行自己主动扫描的时候。设置了sqlSessionFactory 的话。可能会导致PropertyPlaceholderConfigurer失效,也就是用${jdbc_driver_name}这样之类的表达式,将无法获取到properties文件中的内容。 导致这一原因是由于。MapperScannerConigurer实际是在解析载入bean定义阶段的,这个时候要是设置sqlSessionFactory的话,会导致提前初始化一些类。这个时候,
    PropertyPlaceholderConfigurer还没来得及替换定义中的变量。导致把表达式当作字符串复制了。 但假设不设置sqlSessionFactory 属性的话,就必需要保证sessionFactory在spring中名称一定要是sqlSessionFactory 。否则就无法自己主动注入。又或者直接定义MapperFactoryBean 。再或者放弃自己主动代理接口方式。


    能够例如以下方式改动:

    <bean id="propertyConfigurer"  class="com.yowu.common.CustomPropertyPlaceholderConfigurer">
            <property name="locations">
                <list>
                    <value>classpath:important.properties</value>
                </list>
            </property>
         </bean>
    
    	<!-- 配置线程池 -->
    	<bean id="taskExecutor"
    		class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
    		<!-- 线程池维护线程的最少数量 -->
    		<property name="corePoolSize" value="10" />
    		<!-- 线程池维护线程所同意的空暇时间 -->
    		<property name="keepAliveSeconds" value="0" />
    		<!-- 线程池维护线程的最大数量 -->
    		<property name="maxPoolSize" value="10" />
    		<!-- 线程池所使用的缓冲队列 -->
    		<property name="queueCapacity" value="0" />
    	</bean>
    
    	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    		<property name="driverClassName" value="${squirrel_jdbc_driver}" />
    		<property name="url" value="${squirrel_jdbc_url}" />
    		<property name="username" value="${squirrel_jdbc_username}" />
    		<property name="password" value="${squirrel_jdbc_password}" />
    		<property name="validationQuery" value="select 1" />
    		<property name="initialSize" value="5" />
    		<property name="testWhileIdle" value="true" />
    		<property name="maxIdle" value="20" />
    		<property name="minIdle" value="5" />
    		<property name="maxActive" value="50" />
    		<property name="removeAbandonedTimeout" value="180" />
    		<property name="maxWait" value="30000" />
    	</bean>
    
        <bean id="ysqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource"/>
            <property name="mapperLocations" >
                <list>
                    <value>classpath*:mybatis/*.xml</value>
                </list>
            </property>
        </bean>
        <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
            <constructor-arg index="0" ref="ysqlSessionFactory"></constructor-arg>
            <constructor-arg index="1" value="BATCH"></constructor-arg>
        </bean>
    
        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <property name="basePackage" value="com.yowu.dao, com.yowu.app.repository.dao"/>
            <!--核心就是加入以下一句。

    后面那个属性是value。不是ref,切记--> <property name="sqlSessionFactoryBeanName" value="ysqlSessionFactory" /> </bean>



    通过查看MapperScannerConfigurer源代码发现,事实上有这么一段代码:

    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        if (this.processPropertyPlaceHolders) {
          processPropertyPlaceHolders();
        }
    
        Scanner scanner = new Scanner(beanDefinitionRegistry);
        scanner.setResourceLoader(this.applicationContext);
    
        scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS));
      }
    
      /*
       * BeanDefinitionRegistries are called early in application startup, before
       * BeanFactoryPostProcessors. This means that PropertyResourceConfigurers will not have been
       * loaded and any property substitution of this class' properties will fail. To avoid this, find
       * any PropertyResourceConfigurers defined in the context and run them on this class' bean
       * definition. Then update the values.
       */
      private void processPropertyPlaceHolders() {
    大概意思是能够设置processPropertyPlaceHolders为true,强制让PropertyResourceConfigure运行下替换工作。大家最好还是试一下,不一个优雅的解决方案亏损。



    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    HDU1879 kruscal 继续畅通工程
    poj1094 拓扑 Sorting It All Out
    (转)搞ACM的你伤不起
    (转)女生应该找一个玩ACM的男生
    poj3259 bellman——ford Wormholes解绝负权问题
    poj2253 最短路 floyd Frogger
    Leetcode 42. Trapping Rain Water
    Leetcode 41. First Missing Positive
    Leetcode 4. Median of Two Sorted Arrays(二分)
    Codeforces:Good Bye 2018(题解)
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4626127.html
Copyright © 2011-2022 走看看