在启动过程中,Spring警告日志会显示有关创建例如
“名称为'userRepositoryInterface'的bean ...初始化方法的调用失败;嵌套异常为java.lang.IllegalArgumentException:需要属性'sqlSessionFactory'或'sqlSessionTemplate'”
在接下来的几分钟内,每个RepositoryInterface都会重复很多次,但最终问题解决了,应用程序正常运行。
但是启动时间是不可接受的。此外,当我添加新的RepositoryInterface时,启动时间扩展到20分钟,直到服务器(weblogic 12c)内存不足。
这些RepositoryInterfaces的实现类由Spring / Mybatis(spring 4.1.3,mybatis 3.2.8和mybatis-spring 1.2.2)制作,它们扫描(xml)映射器文件来执行此操作。
存储库(DAO)接口自动连接到调用它们的服务类中,例如

@Autowired
private UserRepositoryInterface repository;


存储库接口用@Repository注释
我有一个@Configuration@MapperScan注释的PersistenceConfigurer,其中包含两个@Bean方法:


数据源dataSource()
SqlSessionFactoryBean sqlSessionFactory(DataSource数据源)


直到启动过程结束,才调用dataSource和sqlSessionFactory,这似乎是问题所在。
我试图通过将@Order(0)添加到PersistenceConfigurer来更改此设置,但这没有任何效果。将两个Bean移至其他Configuration类也没有积极作用。
对于Spring,我使用Java配置,没有xml。
为了回应评论,这是整个PersistenceConfigurer:

package org.xx.xxxxxxx.configuration;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jndi.JndiTemplate;

import javax.naming.NamingException;
import javax.sql.DataSource;

/**
 * This class configures the application's persistence layer.
 */
@Configuration
@MapperScan(basePackages = "org.xx.xxxxxxx.repository")
public class PersistenceConfigurer {
    static Logger LOGGER = LogManager.getLogger(PersistenceConfigurer.class);
    @Value("${jdbc.datasource}")
    private String jdbcDatasource;   // in jdbc.properties: jdbc.datasource=jdbc/OurDS

@Value("classpath*:sqlmapper/*.xml")
private Resource[] mapperFiles;

@Value("classpath:mybatisConfig.xml")
private Resource myBatisConfig;

/**
 * @return The configured data source.
 */
@Bean
public DataSource dataSource() {
    JndiTemplate jndiTemplate = new JndiTemplate();
    DataSource dataSource = null;
    LOGGER.debug("Configuring datasource creating datasource with jndiname " + jdbcDatasource);
    try {
        // this works for weblogic,  but not for Tomcat
        dataSource = (DataSource) jndiTemplate.lookup(jdbcDatasource);
        LOGGER.debug("Configuring datasource successfully created datasource " + dataSource);
    } catch (NamingException e) {
        LOGGER.error("Configuring datasource error creating datasource NamingException " + jdbcDatasource);

    } catch (Exception e) {
        LOGGER.error("Configuring datasource error creating datasource " + jdbcDatasource);
        e.printStackTrace();
    }
    return dataSource;
}

/**
 * @param dataSource A configured data source.
 * @return The SQL session factory bean for data management.
 */
@Bean
public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) {
    LOGGER.debug("sqlSessionFactory making SqlSessionFactoryBean with datasource " + dataSource);
    SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
    factoryBean.setDataSource(dataSource);
    factoryBean.setMapperLocations(mapperFiles);
    factoryBean.setConfigLocation(myBatisConfig);
    return factoryBean;
    }
}

最佳答案

我的一位同事找到了主要解决方案:不是返回SqlSessionFactoryBean,而是返回SqlSessionFactory
在此解决方案之前,启动时间取决于RepositoryInterfaces的数量:
5 RepositoryInterfaces:12秒,6:> 80秒; 7:9分钟结束了内存问题。
之后,始终为9秒。

该解决方案无法立即生效,因为多亏了此修复程序,现在该创建才这么早,以至于它在WebMvcConfigurerAdapter中声明的PropertySourcesPlaceholderConfigurer创建之前。
因此,我们将所需属性的解析直接放在PersistenceConfigurer中。谢谢Karthik的建议。

PersistenceConfigurer中更改的代码:
增加的进口:
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

3个更改的私有变量(现在所有3个都是简单的String,没有@Value注释):

private String jdbcDatasource = "jdbc/OurDS";  // moved away from jdbc.properties (was only property left there)

private String mapperFilesLocation = "classpath*:sqlmapper/*.xml";

private String myBatisConfigLocation = "classpath:mybatisConfig.xml";


一种更改的方法,主要更改是返回的对象。添加了三行用于属性解析。

/**
 * @param dataSource A configured data source.
 * @return The SQL session factory (org.apache.ibatis.session.defaults.DefaultSqlSessionFactory).
 * @throws Exception on sqlSessionFactoryBean.getObject(), IOException on resolver.getResources
 */
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) {
    LOGGER.debug("sqlSessionFactory making SqlSessionFactoryBean with datasource " + dataSource);
    SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
    factoryBean.setDataSource(dataSource);
    PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
    Resource[] mapperFiles = resolver.getResources(mapperFilesLocation);
    Resource myBatisConfig = resolver.getResource(myBatisConfigLocation);
    factoryBean.setMapperLocations(mapperFiles);
    factoryBean.setConfigLocation(myBatisConfig);
    return factoryBean.getObject();
}

09-25 19:40