配置Spring Mybatis JUnit测试环境的应用上下文

Spring-test模块中的应用上下文和web及spring boot的有很大差异。主要试下来差异有:

  1. 单元测试的app context不支持从外部properties文件注入属性
  2. @Value注解不能解析带通配符的路径字符串

解决第一个问题可以配置一个PropertyPlaceholderConfigurer的bean。

第二个问题的具体实例是:

    @Value(value = "classpath:mybatis/sqlmap/**/*.xml")

    private Resource[] mapperLocations;

 

解决此问题的一个变通办法是用PathMatchingResourcePatternResolver的getResources()方法来达到相同功能。

 

以下代码是完整的例子:

package com.abc.app1.dao;

import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.pool.DruidDataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;

import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

@Configuration
@MapperScan(basePackageClasses = MapperMarker.class)
@ComponentScan(basePackageClasses = RepositoryMarker.class)
public class UTDalConfig {

    @Bean
    public PropertyPlaceholderConfigurer propertyPlaceHolderConfigurer() {
        PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer();
        Resource resource = new ClassPathResource("application.properties");
        cfg.setLocations(resource);
        return cfg;
    }

    @Bean(autowire = Autowire.BY_NAME)
    public SqlSessionFactoryBean sqlSessionFactory() {
        try {
            SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
            PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            Resource[] mapperLocations = resolver.getResources("classpath:mybatis/sqlmap/**/*.xml");
            ssfb.setMapperLocations(mapperLocations);
            ssfb.setTypeAliasesPackage("com.pajk.ic.api.model.domain");
            return ssfb;
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Bean(initMethod = "init", destroyMethod = "close")
    @Autowired
    public DruidDataSource dataSource(
        @Value("${jdbc.url}") String url,
        @Value("${jdbc.username}") String username,
        @Value("${jdbc.password}") String password,
        @Value("${jdbc.maxActive}") int maxActive,
        @Value("${jdbc.maxWait}") int maxWait,
        @Value("${jdbc.initialSize}") int initialSize,
        @Value("${jdbc.minIdle}") int minIdle,
        @Value("${jdbc.slowSqlMillis}") int slowSqlMillis
    ) throws SQLException {

        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setUrl(url);
        druidDataSource.setUsername(username);
        druidDataSource.setPassword(password);
        druidDataSource.setMaxActive(maxActive);
        druidDataSource.setInitialSize(initialSize);
        druidDataSource.setMaxWait(maxWait);//30s
        druidDataSource.setMinIdle(minIdle);
        druidDataSource.setTimeBetweenEvictionRunsMillis(3000);
        druidDataSource.setMinEvictableIdleTimeMillis(300000);
        druidDataSource.setValidationQuery("select 1");
        druidDataSource.setTestWhileIdle(true);
        druidDataSource.setTestOnBorrow(false);
        druidDataSource.setTestOnReturn(false);
        druidDataSource.setPoolPreparedStatements(true);
        druidDataSource.setMaxPoolPreparedStatementPerConnectionSize(20);
        druidDataSource.setFilters("config");
        Properties properties = new Properties();
        properties.put("config.decrypt", "true");
        druidDataSource.setConnectProperties(properties);
        StatFilter statFilter = new StatFilter();
        statFilter.setSlowSqlMillis(slowSqlMillis);//5s。。慢
        statFilter.setMergeSql(true);

        List<Filter> filterList = new ArrayList<Filter>();
        filterList.add(statFilter);
        druidDataSource.setProxyFilters(filterList);

        return druidDataSource;
    }

    @Bean(autowire = Autowire.BY_NAME)
    public TransactionTemplate transactionTemplate() {
        TransactionTemplate template = new TransactionTemplate();
        return template;
    }

    @Bean(autowire = Autowire.BY_NAME)
    public PlatformTransactionManager transactionManager() {
        return new DataSourceTransactionManager();
    }

}

 此例的数据源配置使用的阿里巴巴的Druid。你可以换成如DBCP,cp30等实现。不过Druid应该是比较强大和稳定的数据库连接池解决方案。

你可能感兴趣的:(spring,mybatis,JUnit)