基于java注解的代码,Spring使用MapperScannerConfigurer无法读取*.properties文件

TGYD 发布于 09/11 14:57
阅读 265
收藏 0

@温安适 大神你好,请教一个问题啊:

基于java注解的代码,我用了selSessionFactoryBeanName属性,Spring使用MapperScannerConfigurer仍然无法读取*.properties

 

源码如下:

package com.wjt.config;

import com.alibaba.druid.pool.DruidDataSource;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
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.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment;
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.stereotype.Repository;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.io.IOException;

/**
 * @Time 2019/9/10/2:42
 * @Author jintao.wang
 * @Description
 */
@Slf4j
@Configuration
@EnableTransactionManagement
@PropertySource(value = "classpath:dbconfig/jdbc.properties", encoding = "UTF-8")
public class DBConfig {

    @Value(value = "${jdbc_driver}")
    private String driverName;

    @Value(value = "${jdbc_url}")
    private String url;

    @Value(value = "${jdbc_user}")
    private String userName;

    @Value(value = "${jdbc_password}")
    private String password;

    @Value(value = "${jdbc_maxActive}")
    private int maxActive;
    @Value(value = "${jdbc_minIdle}")
    private int minIdle;

    @Value(value = "classpath:dbconfig/mybatis_config.xml")
    private Resource configLocation;

    @Value(value = "classpath:mapper/*.xml")
    private Resource[] mapperLocations;

    /*   public static final PathMatchingResourcePatternResolver RESOLVER = new PathMatchingResourcePatternResolver();*/

    @Bean
    public DataSource dataSource() {
        log.info("driverName={};url={};userName={};password={};", driverName, url, userName, password);
        DruidDataSource dataSource = new DruidDataSource();

        dataSource.setDriverClassName(driverName);
        dataSource.setUrl(url);
        dataSource.setMaxActive(maxActive);
        dataSource.setMinIdle(minIdle);
        dataSource.setUsername(userName);
        dataSource.setPassword(password);
        log.info("driverName={};url={};userName={};password={};dataSource={};", driverName, url, userName, password, dataSource);
        return dataSource;
    }


    @Bean(name = {"sqlSessionFactoryBean"})
    public SqlSessionFactoryBean sqlSessionFactoryBean(@Autowired DataSource dataSource) {

/*        Resource configLocation = new ClassPathResource("dbconfig/mybatis_config.xml");
        Resource[] mapperLocations = {new ClassPathResource("mapper/ArticleMapper.xml")};*/

        log.info("configLocation={};mapperLocations={};", configLocation, mapperLocations);
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        sqlSessionFactoryBean.setConfigLocation(configLocation);

        sqlSessionFactoryBean.setMapperLocations(mapperLocations);
        log.info("sqlSessionFactoryBean={};", sqlSessionFactoryBean);
        return sqlSessionFactoryBean;
    }

    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer() {
        log.info("driverName={};url={};userName={};password={};mapperLocations={};", driverName, url, userName, password, mapperLocations);
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setBasePackage("com.wjt.dao");
        mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactoryBean");
        mapperScannerConfigurer.setAnnotationClass(Repository.class);
        //mapperScannerConfigurer.setProcessPropertyPlaceHolders(true);
        log.info("mapperScannerConfigurer={};", mapperScannerConfigurer);
        return mapperScannerConfigurer;
    }


    @Bean
    public PlatformTransactionManager transactionManager(@Autowired DataSource dataSource) {
        PlatformTransactionManager transactionManager = new DataSourceTransactionManager(dataSource);
        log.info("transactionManager={};", transactionManager);
        return transactionManager;
    }

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
        log.info("propertySourcesPlaceholderConfigurer={};", propertySourcesPlaceholderConfigurer);
        return propertySourcesPlaceholderConfigurer;
    }

/*    @Bean
    public static PropertyPlaceholderConfigurer propertyPlaceholderConfigurer(){
        PropertyPlaceholderConfigurer propertyPlaceholderConfigurer=new PropertyPlaceholderConfigurer();
        log.info("propertyPlaceholderConfigurer={};",propertyPlaceholderConfigurer);
        return propertyPlaceholderConfigurer;
    }*/

}

jdbc.properties配置文件如下:

jdbc_driver=com.mysql.cj.jdbc.Driver
jdbc_url=jdbc:mysql://localhost:3306/ssm_train?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true
jdbc_user=root
jdbc_password=linux2014
jdbc_maxActive=10
jdbc_minIdle=1
jdbc_driver_class_path=C:/Users/17460/.m2/repository/mysql/mysql-connector-java/6.0.6/mysql-connector-java-6.0.6.jar

 

测试用例代码如下:

package com.wjt.config;

import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;
import javax.sql.DataSource;

import static org.junit.Assert.*;

@Slf4j
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {DBConfig.class})
public class DBConfigTest {
    @Resource
    private DataSource dataSource;

    @Test
    public void db() {
        log.info("dataSource={};", dataSource);
    }
}

 

 

执行测试用例的结果如下:

这时无法读取jdbc.properties文件内的内容。

 

但是删除DBConfig.mapperScannerConfigurer()这个方法后就可以成功读取了。

请大神帮忙分析一下原因和解决办法吧!先行谢过了。

 

 

 

 

加载中
0
温安适
温安适

先拆分出一个类DBConfig,仅仅包含你的属性,不要包含对应的方法。

之后再写一个类,例如叫DataSourceConfig。

包含你对应的方法,注意,这些方法要改写

@Bean
public DataSource dataSource(@Autowired DBConfig dbCondig) 
// 其他方法也是一样的

个人任务DBconfig本身是个bean,被@Bean注解的方法也是个bean,被Spring管理起来了,如果DBConfig在dataSource之后被实例化(new+设置属性)就会出现你的问题。

 

0
温安适
温安适

上边的情况可能是,DBconfig 被反射出来了,还没有populateBean(就是设置属性值)

0
T
TGYD

大神,按你说的修改了的代码,如下:

属性类:

package com.wjt.config;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
import org.springframework.test.context.ContextConfiguration;

/**
 * @Time 2019/9/11/15:45
 * @Author jintao.wang
 * @Description
 */
@Slf4j
@Data
@Component
@Configuration
@PropertySource(value = "classpath:dbconfig/jdbc.properties", encoding = "UTF-8")
public class DBProperty {

    @Value(value = "${jdbc_driver}")
    private String driverName;

    @Value(value = "${jdbc_url}")
    private String url;

    @Value(value = "${jdbc_user}")
    private String userName;

    @Value(value = "${jdbc_password}")
    private String password;

    @Value(value = "${jdbc_maxActive}")
    private int maxActive;
    @Value(value = "${jdbc_minIdle}")
    private int minIdle;

    @Value(value = "classpath:dbconfig/mybatis_config.xml")
    private Resource configLocation;

    @Value(value = "classpath:mapper/*.xml")
    private Resource[] mapperLocations;

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
        log.info("propertySourcesPlaceholderConfigurer={};", propertySourcesPlaceholderConfigurer);
        return propertySourcesPlaceholderConfigurer;
    }
}

bean配置类:

package com.wjt.config;

import com.alibaba.druid.pool.DruidDataSource;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.PlatformTransactionManager;

import javax.annotation.Resource;
import javax.sql.DataSource;

/**
 * @Time 2019/9/11/15:45
 * @Author jintao.wang
 * @Description
 */

@Slf4j
@Configuration
@Import(value = {DBProperty.class})
public class MySQLConfig {


    @Bean
    public DataSource dataSource(@Autowired DBProperty dbProperty) {
        String driverName = dbProperty.getDriverName();
        String url = dbProperty.getUrl();
        String userName = dbProperty.getUserName();
        String password = dbProperty.getPassword();
        int maxActive = dbProperty.getMaxActive();
        int minIdle = dbProperty.getMinIdle();
        log.info("driverName={};url={};userName={};password={};", driverName, url, userName, password);
        DruidDataSource dataSource = new DruidDataSource();

        dataSource.setDriverClassName(driverName);
        dataSource.setUrl(url);
        dataSource.setMaxActive(maxActive);
        dataSource.setMinIdle(minIdle);
        dataSource.setUsername(userName);
        dataSource.setPassword(password);
        log.info("driverName={};url={};userName={};password={};dataSource={};", driverName, url, userName, password, dataSource);
        return dataSource;
    }


    @Bean(name = {"sqlSessionFactoryBean"})
    public SqlSessionFactoryBean sqlSessionFactoryBean(@Autowired DataSource dataSource,@Autowired DBProperty dbProperty) {

        org.springframework.core.io.Resource configLocation = dbProperty.getConfigLocation();
        org.springframework.core.io.Resource[] mapperLocations = dbProperty.getMapperLocations();

/*        Resource configLocation = new ClassPathResource("dbconfig/mybatis_config.xml");
        Resource[] mapperLocations = {new ClassPathResource("mapper/ArticleMapper.xml")};*/

        log.info("configLocation={};mapperLocations={};", configLocation, mapperLocations);
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        sqlSessionFactoryBean.setConfigLocation(configLocation);

        sqlSessionFactoryBean.setMapperLocations(mapperLocations);
        log.info("sqlSessionFactoryBean={};", sqlSessionFactoryBean);
        return sqlSessionFactoryBean;
    }

    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(@Autowired DBProperty dbProperty) {

        String driverName = dbProperty.getDriverName();
        String url = dbProperty.getUrl();
        String userName = dbProperty.getUserName();
        String password = dbProperty.getPassword();
        int maxActive = dbProperty.getMaxActive();
        int minIdle = dbProperty.getMinIdle();
        org.springframework.core.io.Resource configLocation = dbProperty.getConfigLocation();
        org.springframework.core.io.Resource[] mapperLocations = dbProperty.getMapperLocations();

        log.info("driverName={};url={};userName={};password={};mapperLocations={};", driverName, url, userName, password, mapperLocations);
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setBasePackage("com.wjt.dao");
        mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactoryBean");
        mapperScannerConfigurer.setAnnotationClass(Repository.class);
        //mapperScannerConfigurer.setProcessPropertyPlaceHolders(true);
        log.info("mapperScannerConfigurer={};", mapperScannerConfigurer);
        return mapperScannerConfigurer;
    }


    @Bean
    public PlatformTransactionManager transactionManager(@Autowired DataSource dataSource) {
        PlatformTransactionManager transactionManager = new DataSourceTransactionManager(dataSource);
        log.info("transactionManager={};", transactionManager);
        return transactionManager;
    }


}

运行日志如下:

0
妹子楼顶有鸽子
妹子楼顶有鸽子
MapperScannerConfigurer<--BeanDefinitionRegistryPostProcessor<--BeanFactoryPostProcessor
BeanFactoryPostProcessor的处理优先级大于Bean的初始化,所以这样是注入不进来的...
0
T
TGYD

那应该怎么修改,才能保证正确呢?

0
温安适
温安适

你的第二个配置也可以,不过要修改,import的位置MySQLConfig去掉Import  DBProperty中加入,如下

@Configuration
@Component
@Import(value = {MySQLConfig.class})
public class DBProperty {

 

 

0
温安适
温安适

spring 官方文档中的例子

0
温安适
温安适

如果还有问题,请@温安适

返回顶部
顶部