我有一个基于Spring JDBC和Jersey RESTful Web服务的Web应用程序。我使用以下Spring JDBC模板类来启动dataSource并执行SQL脚本(update_condition_table.sql):
public class CustomerJDBCTemplate implements CustomerDAO {
private DataSource dataSource;
private JdbcTemplate jdbcTemplateObject;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
this.jdbcTemplateObject = new JdbcTemplate(dataSource);
Resource rc = new ClassPathResource("update_condition_table.sql");
JdbcTestUtils.executeSqlScript(jdbcTemplateObject, rc, false);
}
// ......other methods
}
bean配置文件是beans.xml:
<!-- Initialization for data source -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/customer" />
<property name="username" value="root" />
<property name="password" value="mypassword" />
</bean>
<!-- Definition for customerJDBCTemplate bean -->
<bean id="customerJDBCTemplate" class="com.example.db.CustomerJDBCTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
Jersey控制器类包含类CustomerJDBCTemplate
的实例化,并用作REST Web服务:
@Path("/customer")
public class CustomerService {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
CustomerJDBCTemplate dbController = (CustomerJDBCTemplate) context.getBean("customerJDBCTemplate");
// ... some GET/POST methods
}
当我通过在浏览器中输入索引URL来启动我的Web应用程序时,SQL脚本由customerJDBCTemplate
bean执行。但是,当我单击导航到其他页面时,它崩溃并报告无法再次执行SQL脚本。显然,在初始化dataSource并初始启动索引网页后,SQL脚本再次被执行。如何通过在Web应用程序初次启动时仅运行一次SQL脚本来避免这种情况?
看起来我需要将bean实例化代码移出CustomerService
类,但是我应该把代码放在哪里?
答案 0 :(得分:1)
我认为我应该将bean应用程序上下文设置为CustomerService
类中的静态,并在静态初始化块中执行,如下所示:
@Path("/customer")
public class CustomerService {
private static ApplicationContext context;
private static CustomerJDBCTemplate dbController;
static {
context = new ClassPathXmlApplicationContext("beans.xml");
dbController = (CustomerJDBCTemplate) context.getBean("customerJDBCTemplate");
}
//... other methods
}
我想原因是Jersey为每个HTTP会话创建了一个不同的CustomerService
实例(如果我错了,请纠正我)。因此,如果我将bean上下文设置为实例变量,它将为每个HTTP请求执行初始化。
答案 1 :(得分:0)
让您的CustomerJDBCTemplate实施InitializingBean。在Spring的BeanFactory设置了所有属性后,afterPropertiesSet
将被调用一次。
例如:
public class CustomerJDBCTemplate implements CustomerDAO, InitializingBean {
...
// ......other methods
public void afterPropertiesSet() throws Exception {
//do your initializing, or call your initializing methods
}
}