2013-07-01 178 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請求執行初始化。