为什么在Spring中初始化JFinal 数据库出错?

你好,我最近的一个项目中希望在Spring MVC框架下利用JFinal的数据库操作功能。在XML中我成功配置了数据源,但是对JFinal进行数据库初始化操作的时候出现Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Config already exists: main 错误,请问是什么原因?具体代码和XML配置如下:

@Component
public class ActiveRecordConfig{
    // 测试所用jfinal model
	
	@Autowired private DruidDataSource DSTestFilght;
    @Bean(initMethod="start", destroyMethod="stop")
	public ActiveRecordPlugin init() {
		// 加载FRAMS数据库内容
		ActiveRecordPlugin arpFRAMS = new ActiveRecordPlugin(DSTestFilght);
		arpFRAMS.setDialect(new SqlServerDialect());
		arpFRAMS.addMapping("RawFileInfo", "OF_ID", RawFileInfoModel.class);
		return arpFRAMS;
	}
}

    <bean id="DSTestFilght" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">   
    	<!-- 基本属性 url、user、password -->  
    	<property name="url" value="${FRAMS.url}" />  
    	<property name="username" value="${FRAMS.username}" />  
    	<property name="password" value="${FRAMS.password}" />  
        
    	<!-- 配置初始化大小、最小、最大 -->  
    	<property name="initialSize" value="1" />  
    	<property name="minIdle" value="1" />   
    	<property name="maxActive" value="20" />  
   
    	<!-- 配置获取连接等待超时的时间 -->  
    	<property name="maxWait" value="60000" />  
   
    	<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->  
    	<property name="timeBetweenEvictionRunsMillis" value="60000" />  
   
    	<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->  
    	<property name="minEvictableIdleTimeMillis" value="300000" />  
    
    	<property name="validationQuery" value="SELECT 'x'" />  
    	<property name="testWhileIdle" value="true" />  
    	<property name="testOnBorrow" value="false" />  
    	<property name="testOnReturn" value="false" />  
   
    	<!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->  
    	<property name="poolPreparedStatements" value="true" />  
    	<property name="maxPoolPreparedStatementPerConnectionSize" value="20" />  
   
    	<!-- 配置监控统计拦截的filters,去掉后监控界面sql无法统计 -->  
    	<property name="filters" value="stat" />   
	</bean>



评论区

linuxea

2017-07-26 11:11

ActiveRecordPlugin arpFRAMS = new ActiveRecordPlugin(DSTestFilght);
其他地方会不会也配置了默认名称为main的recordplugin呢?
试试ActiveRecordPlugin arpFRAMS = new ActiveRecordPlugin("这里添加一个名称,不过感觉解决不了根本问题",DSTestFilght);

JFinal

2017-07-26 11:17

你的项目在某处已经创建了一个 ActiveRecordPlugin 对象,而这个对象会有一个默认的 Config 对象,并且名字叫: "main"

而你的项目又再次创建了 ActiveRecordPlugin 对象,而 Config 对象的名字是不能重复的,在 ActiveRcordPlugin 的构造方法中添加断点,就能很快定位到是哪两处重复创建了这个 ActiveRecordPlugin

devil2k

2017-07-26 11:18

@linuxea 因为刚开始学着用,就这一个地方配了,我测试中发现init被运行了两次,所以相当于start方法被调用了两次,但是如果把@Bean后面括号的东西注释掉的话,就无法进行数据库访问操作了。这段程序我是从这里扒过来,感觉应该没错啊。。。https://www.oschina.net/code/snippet_813039_49993

linuxea

2017-07-26 11:19

@JFinal 我觉得得奇怪的是为什么会创建多次呢。明明交给spring完成bean的管理了。而且从上面的配置信息来看bean是使用默认的生命周期单例的哩

JFinal

2017-07-26 11:21

@devil2k 你只要保障一下 init 方法只被运行一次,也就是说 ActiveRecordPlugin 只被 new 出来一次就可以了

JFinal

2017-07-26 11:21

@linuxea tomcat 有这种坑:https://my.oschina.net/jfinal/blog/353062
一个项目被启动两次

devil2k

2017-07-26 11:22

@JFinal 对啊,我也纳闷为什么init方法会被运行两次呢?难道跟@Compoment注释有关?

devil2k

2017-07-26 11:22

@linuxea 说的就是啊

JFinal

2017-07-26 11:23

@devil2k 好多年不用 spring,这个 init 被运行两次的问题只能交给你了

devil2k

2017-07-26 11:27

http://blog.csdn.net/u010131956/article/details/60882464,貌似这个是原因

devil2k

2017-07-26 11:27

而且加一个hasInitedFlag状态量记录后,解决了

JFinal

2017-07-26 11:56

@devil2k 加 hasInitedFlag 这个变量控制,治标不治本,其它的对象仍然被初始化两次,将来如果你有任务调度的类被创建两次,那么这些任务会被执行两次,可能造成很大损失

ThreeX

2017-07-28 12:41

最近想重新学习一下spring,缘因看到搜狗的一个开源项目cynthia,感觉不错,看了一下源码,发现用的是spring一桶,想研究一波!

热门反馈

扫码入社