Spring上下文加载器

时间:2015-03-31 08:28:42

标签: spring scheduler applicationcontext

我有一个关于春天背景的问题。我的应用程序使用弹簧和弹簧调度程序。 在web.xml中,我声明:

<listener> 
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

我的问题是:

如果我在web.xml中声明org.springframework.web.context.ContextLoaderListener,则调度程序将运行两次,所有bean都是重复的,应用程序启动时间约为160秒。

如果我删除org.springframework.web.context.ContextLoaderListener, spring抛出异常:No WebApplicationContext found: no ContextLoaderListener registered。应用启动时间减少到80秒。

我该如何解决?谢谢大家!

3 个答案:

答案 0 :(得分:0)

谢谢@ M.Deinum,但我不明白你的想法。 这是我的web.xml:

<context-param>
    <param-name>contextClass</param-name>
    <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
  </context-param>

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>com.htc.epos.api.bootstrap</param-value>
  </context-param>

  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <servlet>
    <servlet-name>webapp</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextClass</param-name>
      <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
    </init-param>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>
              com.htc.epos.api.bootstrap.WebAppConfig
              com.htc.epos.api.bootstrap.AppConfig
      </param-value>
    </init-param>
  </servlet>

答案 1 :(得分:0)

Think @ M.Deinum是对的;通过远程处理和正常情况分割你的bean。我在我的web.xml中执行此操作:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/classes/spring/root-context.xml</param-value>
</context-param>

<servlet>
    <servlet-name>remoting</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/classes/spring/remoting-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>remoting</servlet-name>
    <url-pattern>/remoting/*</url-pattern>
</servlet-mapping>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

root-context.xml包含我所有的普通bean(服务,助手,计算器,jms监听器,计划任务等)。

remoting-servlet.xml仅指定需要通过HttpInvokerServiceExporter公开的服务。除了导出器的ref =“historyWebService”之外,根目录中没有定义bean的导入或链接。

根据我的理解,你最终会得到2个应用程序上下文:1个root和1个remoting。远程处理器继承了root中的所有bean,因此你不会两次声明或实例化bean(我认为)!我确定似乎没有产生重复的bean(即2个任务,2个jms监听器等)。

答案 2 :(得分:0)

我有2个文件配置:

1. AppConfig:

    @Configuration
    @EnableScheduling
    @EnableTransactionManagement
    @EnableJpaRepositories("com.test.api.repository")
    @PropertySource("classpath:application.properties")
    public class AppConfig {
          ...............
    }

2. WebInitializer

public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

  @Override
  protected Class<?>[] getRootConfigClasses() {
    return new Class<?>[0];
  }

  @Override
  protected Class<?>[] getServletConfigClasses() {
    return new Class<?>[] { WebAppConfig.class };
  }

  @Override
  protected String[] getServletMappings() {
    return new String[] { "/" };
  }

  @Configuration
  @EnableWebMvc
  @ComponentScan(basePackages = {"com.test.api"})
  public static class WebAppConfig extends WebMvcConfigurerAdapter {

    ...................
   }
}

在WebAppConfig中,如果我将@ComponentScan(basePackages = {"com.test.api"})更改为Web包@ComponentScan(basePackages = {"com.test.api.web"}),那么spring bean不会重复,调度程序也不会运行两次。但有时它会抛出异常:

 error: org.hibernate.LazyInitializationException: could not initialize proxy - no Session