2013-07-01 179 views
0

我有一个基于Spring JDBC和Jersey RESTful Web服务的Web应用程序。我使用下面的Spring JDBC模板类发起DataSource和执行SQL脚本(update_condition_table.sql):如何在Spring中启动时只执行一次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> 

泽西控制器类包含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

让您的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 
    } 
} 
+0

这对我尝试后没有帮助。但是,我找到了正确的方法(请参阅下面的自我回答)。 – tonga

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请求执行初始化。