Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么每次访问servlet时都会重新加载Spring应用程序上下文?_Spring_Servlets_Quartz Scheduler - Fatal编程技术网

为什么每次访问servlet时都会重新加载Spring应用程序上下文?

为什么每次访问servlet时都会重新加载Spring应用程序上下文?,spring,servlets,quartz-scheduler,Spring,Servlets,Quartz Scheduler,几个月前,我制作了一个简单的应用程序,只要在数据库中找到某些条件,就可以每晚运行,向我的用户发送电子邮件。我使用Spring3.1.0和Quartz 1.8.5来实现这一点;到目前为止,一切顺利 该应用程序部署在weblogic服务器中 上周,我被要求修改该应用程序,允许手动命令它通过URL运行 我向它添加了一个servlet,它工作得很好:每次有人调用URL时,应用程序都会运行 但是出现了一个副作用——每次servlet调用都会引发spring上下文的重新加载,并创建另一个Quartz实例。所

几个月前,我制作了一个简单的应用程序,只要在数据库中找到某些条件,就可以每晚运行,向我的用户发送电子邮件。我使用Spring3.1.0和Quartz 1.8.5来实现这一点;到目前为止,一切顺利

该应用程序部署在weblogic服务器中

上周,我被要求修改该应用程序,允许手动命令它通过URL运行

我向它添加了一个servlet,它工作得很好:每次有人调用URL时,应用程序都会运行

但是出现了一个副作用——每次servlet调用都会引发spring上下文的重新加载,并创建另一个Quartz实例。所以,如果上述servlet被调用n次,当Quartz解雇我的工作时,我的应用程序将发送n+1封重复的电子邮件,而不是仅发送1封

我想了解为什么会发生这种情况,以及如何解决这一问题。你能帮帮我吗

以下是与我的问题相关的文件

日志文件摘录,包括应用程序的启动:

28/11/2012 16:37:48 org.springframework.web.context.ContextLoader initWebApplicationContext
INFO: Root WebApplicationContext: initialization started
28/11/2012 16:37:48 org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing Root WebApplicationContext: startup date [Wed Nov 28 16:37:48 BRST 2012]; root of context hierarchy
28/11/2012 16:37:48 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from URL [file:/C:/bea/user_projects/workspaces/app/target/app-1.0.0/WEB-INF/classes/app-context.xml]
28/11/2012 16:37:48 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [app-data-context.xml]
28/11/2012 16:37:48 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [app-scheduler.xml]
28/11/2012 16:37:48 org.springframework.core.io.support.PropertiesLoaderSupport loadProperties
INFO: Loading properties file from class path resource [app.properties]
28/11/2012 16:37:48 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@599bcd: defining beans [org.springframework.beans.factory.config.PropertyPlaceholderConfigurer#0,appDS,job,cronTrigger,org.springframework.scheduling.quartz.SchedulerFactoryBean#0,appDAO,appService,mailerService,appTask, (...)]; root of factory hierarchy
28/11/2012 16:37:50 org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup start
INFO: Starting beans in phase 2147483647

**28/11/2012 16:37:50 org.springframework.scheduling.quartz.SchedulerFactoryBean startScheduler
INFO: Starting Quartz Scheduler now**

28/11/2012 16:37:50 org.springframework.web.context.ContextLoader initWebApplicationContext
INFO: Root WebApplicationContext: initialization completed in 2109 ms
每次调用servlet时发生的日志文件摘录:

<28/11/2012 16h37min50s BRST> <Notice> <WebLogicServer> <BEA-000360> <Server started in RUNNING mode> 
28/11/2012 16:39:06 org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@11f7458: startup date [Wed Nov 28 16:39:06 BRST 2012]; root of context hierarchy
28/11/2012 16:39:06 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [app-context.xml]
28/11/2012 16:39:06 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [app-data-context.xml]
28/11/2012 16:39:06 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [app-scheduler.xml]
28/11/2012 16:39:06 org.springframework.core.io.support.PropertiesLoaderSupport loadProperties
INFO: Loading properties file from class path resource [app.properties]
28/11/2012 16:39:06 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@10ca001: defining beans [(...)]; root of factory hierarchy
28/11/2012 16:39:06 org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup start
INFO: Starting beans in phase 2147483647
**28/11/2012 16:39:06 org.springframework.scheduling.quartz.SchedulerFactoryBean startScheduler
INFO: Starting Quartz Scheduler now**
非常感谢您抽出时间

解决方案 ---根据@Boris信息,我稍微修改了一下servlet。我的上下文已经加载,我只需要访问它:

public class AppServlet extends HttpServlet   {

    private static final long serialVersionUID = 7213474106234238692L;

    ApplicationContext applicationContext = null;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        PrintWriter out = resp.getWriter();

        out.println("execução iniciada em: " + new Date());
         if (applicationContext == null){
                applicationContext = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
        }
        GerenciadorTasks gt = (GerenciadorTasks) applicationContext.getBean(SpringNameBeans.GERENCIADOR_TASKS);
        gt.init();
        out.println("execução terminada em: " + new Date());

    }

}

在您的代码中,您正在为每个GET方法创建一个新的应用程序上下文,您应该在servlet init()方法中创建上下文,或者改用Web App root contet:

public class AppServlet extends HttpServlet   {

@Autowired
ApplicationContext applicationContext;

@Override
public void init(ServletConfig arg0) throws ServletException {
     WebApplicationContextUtils.getWebApplicationContext(arg0.getServletContext())
        .getAutowireCapableBeanFactory().autowireBean(this);
}

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        PrintWriter out = resp.getWriter();

        out.println("execução iniciada em: " + new Date());

        GerenciadorTasks gt = (GerenciadorTasks) this.applicationContext.getBean(SpringNameBeans.GERENCIADOR_TASKS);
        gt.init();
        out.println("execução terminada em: " + new Date());

    }
}
不清楚您的GerenciadorTasks是否是单例的,所以在我的回答中,我使用了getbean()而不是自动连接在每个GET请求上调用init()不太可能是您想要做的事情。 另外,请注意,已在您的配置中使用创建了

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:app-context.xml</param-value>
    </context-param>

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

上下文配置位置
classpath*:app-context.xml
org.springframework.web.context.ContextLoaderListener

如果您想在Spring中使用调度,请考虑使用.< /P>


因此,我认为仅将根web应用程序上下文与调度api一起使用是可行的。另请看。

br.com.app.publicInterface.appServlet的来源是什么?它是如何与spring集成的?servlet生命周期方法等?@BorisTreukhov,我将在问题中添加appServlet源代码。谢谢你的关注。谢谢你令人敬畏和完整的答复-它显示了我的错误。另外,感谢您的链接,它们包含有价值的信息。我以一种与你的提议相似的方式解决了这个问题。为了其他人的利益,我将把新的servlet代码放在我的问题中,并结束这个问题。注意:GerenciadorTasks的init方法是我的一个方法,而不是像servlet那样的某个API的一个方法-只是在应用程序上下文之外有误导性的名称:)
public class AppServlet extends HttpServlet   {

    private static final long serialVersionUID = 7213474106234238692L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        PrintWriter out = resp.getWriter();

        out.println("execução iniciada em: " + new Date());
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:app-context.xml");   
        GerenciadorTasks gt = (GerenciadorTasks) context.getBean(SpringNameBeans.GERENCIADOR_TASKS);
        gt.init();
        out.println("execução terminada em: " + new Date());

    }

}
public class AppServlet extends HttpServlet   {

    private static final long serialVersionUID = 7213474106234238692L;

    ApplicationContext applicationContext = null;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        PrintWriter out = resp.getWriter();

        out.println("execução iniciada em: " + new Date());
         if (applicationContext == null){
                applicationContext = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
        }
        GerenciadorTasks gt = (GerenciadorTasks) applicationContext.getBean(SpringNameBeans.GERENCIADOR_TASKS);
        gt.init();
        out.println("execução terminada em: " + new Date());

    }

}
public class AppServlet extends HttpServlet   {

@Autowired
ApplicationContext applicationContext;

@Override
public void init(ServletConfig arg0) throws ServletException {
     WebApplicationContextUtils.getWebApplicationContext(arg0.getServletContext())
        .getAutowireCapableBeanFactory().autowireBean(this);
}

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        PrintWriter out = resp.getWriter();

        out.println("execução iniciada em: " + new Date());

        GerenciadorTasks gt = (GerenciadorTasks) this.applicationContext.getBean(SpringNameBeans.GERENCIADOR_TASKS);
        gt.init();
        out.println("execução terminada em: " + new Date());

    }
}
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:app-context.xml</param-value>
    </context-param>

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