2013-01-08 25 views
3

我開始學習Spring MVC。我試圖擺脫所有Spring XML配置。這是我的web.xml:Spring MVC,配置的兩個實例而不是一個

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
    version="3.0"> 
    <!-- Configure ContextLoaderListener to use AnnotationConfigWebApplicationContext 
     instead of the default XmlWebApplicationContext --> 
    <context-param> 
     <param-name>contextClass</param-name> 
     <param-value> 
      org.springframework.web.context.support.AnnotationConfigWebApplicationContext 
     </param-value> 
    </context-param> 

    <!-- Configuration locations must consist of one or more comma- or space-delimited 
     fully-qualified @Configuration classes. Fully-qualified packages may also be 
     specified for component-scanning --> 
    <context-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>pl.mbrnwsk.sklep.config.AppConfiguration</param-value> 
    </context-param> 

    <!-- Bootstrap the root application context as usual using ContextLoaderListener --> 
    <listener> 
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener> 

    <!-- Declare a Spring MVC DispatcherServlet as usual --> 
    <servlet> 
     <servlet-name>dispatcher</servlet-name> 
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
     <!-- Configure DispatcherServlet to use AnnotationConfigWebApplicationContext 
      instead of the default XmlWebApplicationContext --> 
     <init-param> 
      <param-name>contextClass</param-name> 
      <param-value> 
       org.springframework.web.context.support.AnnotationConfigWebApplicationContext 
      </param-value> 
     </init-param> 
     <!-- Again, config locations must consist of one or more comma- or space-delimited 
      and fully-qualified @Configuration classes --> 
     <init-param> 
      <param-name>contextConfigLocation</param-name> 
      <param-value>pl.mbrnwsk.sklep.config.AppConfiguration</param-value> 
     </init-param> 
    </servlet> 

    <!-- map all requests for/to the dispatcher servlet --> 
    <servlet-mapping> 
     <servlet-name>dispatcher</servlet-name> 
     <url-pattern>/</url-pattern> 
    </servlet-mapping> 
</web-app> 

Appconfiguration.java:

@Configuration 
@EnableTransactionManagement 
@ComponentScan("pl.mbrnwsk.sklep") 
public class AppConfiguration { 

    public String hbm2ddl_auto = "update"; 

    public AppConfiguration(){ 
     System.out.println("AppConfiguration"); 
    } 

    @Bean 
    public ViewResolver viewResolver(){ 
     InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); 
     viewResolver.setPrefix("/"); 
     viewResolver.setSuffix(".jsp"); 
     return viewResolver; 
    } 

    @Bean 
    public DataSource dataSource() { 
     DriverManagerDataSource ds = new DriverManagerDataSource(); 
     ds.setDriverClassName("org.hsqldb.jdbcDriver"); 
     ds.setUrl("jdbc:hsqldb:file:/SklepDB/"); 
     ds.setUsername("SA"); 
     ds.setPassword(""); 
     return ds; 
    } 

    @Bean 
    public SessionFactory sessionFactory() { 
     LocalSessionFactoryBuilder ss = new LocalSessionFactoryBuilder(dataSource()); 
     ss.scanPackages("pl.mbrnwsk.sklep.model"); 
     ss.setProperty("hibernate.show_sql", "true"); 
     ss.setProperty("hibernate.hbm2ddl.auto", hbm2ddl_auto); 
     ss.setProperty("hibernate.dialect", 
       "org.hibernate.dialect.HSQLDialect"); 
     return ss.buildSessionFactory(); 
    } 

    @Bean 
    public PlatformTransactionManager txManager(){ 
     return new HibernateTransactionManager(sessionFactory()); 
    } 
} 

AppConfiguration的實例被創建兩次:一次是當我啓動Tomcat,兩次,當我進入一些網址,應該是由調度員處理。這不是期望的行爲。我希望只使用Tomcat來創建AppConfiguration。如何實現這一目標? 第二個問題,聽衆做了什麼?

回答

4

這裏的問題在於您對servlet和根上下文使用相同的配置。這就是爲什麼你有兩個配置實例。在Spring MVC中,你有2個上下文,servlet上下文和根上下文。 servlet上下文適用於您的控制器以及業務對象和服務的根上下文。

如果您不想使用XML,請創建兩個配置類。事情是這樣的:

根上下文

@Configuration 
@EnableTransactionManagement 
@ComponentScan("pl.mbrnwsk.sklep") 
public class AppConfiguration { 

    public String hbm2ddl_auto = "update"; 

    public AppConfiguration(){ 
     System.out.println("AppConfiguration"); 
    } 

    @Bean 
    public DataSource dataSource() { 
     DriverManagerDataSource ds = new DriverManagerDataSource(); 
     ds.setDriverClassName("org.hsqldb.jdbcDriver"); 
     ds.setUrl("jdbc:hsqldb:file:/SklepDB/"); 
     ds.setUsername("SA"); 
     ds.setPassword(""); 
     return ds; 
    } 

    @Bean 
    public SessionFactory sessionFactory() { 
     LocalSessionFactoryBuilder ss = new LocalSessionFactoryBuilder(dataSource()); 
     ss.scanPackages("pl.mbrnwsk.sklep.model"); 
     ss.setProperty("hibernate.show_sql", "true"); 
     ss.setProperty("hibernate.hbm2ddl.auto", hbm2ddl_auto); 
     ss.setProperty("hibernate.dialect", 
       "org.hibernate.dialect.HSQLDialect"); 
     return ss.buildSessionFactory(); 
    } 

    @Bean 
    public PlatformTransactionManager txManager(){ 
     return new HibernateTransactionManager(sessionFactory()); 
    } 
} 

servlet上下文

@Configuration 
@ComponentScan("pl.mbrnwsk.sklep.controller") 
public class ServletConfiguration { 

    public AppConfiguration(){ 
     System.out.println("ServletConfiguration"); 
    } 

    @Bean 
    public ViewResolver viewResolver(){ 
     InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); 
     viewResolver.setPrefix("/"); 
     viewResolver.setSuffix(".jsp"); 
     return viewResolver; 
    } 
} 

web.xml中

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
     version="3.0"> 
     <!-- Configure ContextLoaderListener to use AnnotationConfigWebApplicationContext 
      instead of the default XmlWebApplicationContext --> 
     <context-param> 
      <param-name>contextClass</param-name> 
      <param-value> 
       org.springframework.web.context.support.AnnotationConfigWebApplicationContext 
      </param-value> 
     </context-param> 

     <!-- Configuration locations must consist of one or more comma- or space-delimited 
      fully-qualified @Configuration classes. Fully-qualified packages may also be 
      specified for component-scanning --> 
     <context-param> 
      <param-name>contextConfigLocation</param-name> 
      <param-value>pl.mbrnwsk.sklep.config.AppConfiguration</param-value> 
     </context-param> 

     <!-- Bootstrap the root application context as usual using ContextLoaderListener --> 
     <listener> 
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
     </listener> 

     <!-- Declare a Spring MVC DispatcherServlet as usual --> 
     <servlet> 
      <servlet-name>dispatcher</servlet-name> 
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
      <!-- Configure DispatcherServlet to use AnnotationConfigWebApplicationContext 
       instead of the default XmlWebApplicationContext --> 
      <init-param> 
       <param-name>contextClass</param-name> 
       <param-value> 
        org.springframework.web.context.support.AnnotationConfigWebApplicationContext 
       </param-value> 
      </init-param> 
      <!-- Again, config locations must consist of one or more comma- or space-delimited 
       and fully-qualified @Configuration classes --> 
      <init-param> 
       <param-name>contextConfigLocation</param-name> 
       <param-value>pl.mbrnwsk.sklep.config.ServletConfiguration</param-value> 
      </init-param> 
     </servlet> 

     <!-- map all requests for/to the dispatcher servlet --> 
     <servlet-mapping> 
      <servlet-name>dispatcher</servlet-name> 
      <url-pattern>/</url-pattern> 
     </servlet-mapping> 
</web-app> 
+0

謝謝,現在很清楚。 – user1091733

0

我發現通過將我的@Configuration類作爲ContextConfigLocation包含進來,而不是通過組件掃描來識別它們,我避免了將創建重複ListableBeanFactories並鎖定Hibernate SessionFactory的內存泄漏。

相關問題