zoukankan      html  css  js  c++  java
  • spring配置加载2次实例问题。

    WEB.XML 中SPRING 配置及重复加载问题

    项目内存溢出,mat 查看了一下发现spring 存在两个实例。回过头看启动日志,果然spring被重复加载了。

    在实际项目中spring的配置文件 applicationcontext.xml是通过spring提供的加载机制,自动加载的容器中去,在web项目中,配置文件加载到web容器中进行 解析,目前,spring提供了两种加载器,以供web容器的加载:一种是ContextLoaderListener,另一种是 ContextLoaderServlet。这两种在功能上完全相同,只是一种是基于Servlet2.3版本中新引入的Listener接口实现,而另 一种是基于Servlet接口实现,以下是这两种加载器在web.xml中的时机配置应用:

    第一种:

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

    另一种:

    <servlet>
     <servlet-name>context</servlet-name>
     <servlet-class>org.springframework.context.ContextLoaderServlet</servlet-class>
     <load-on-startup>1</load-on-startup>
    </servlet>

    通过上面的配置,web容器会自动加载applicationcontext.xml初始化。

    如果需要指定配置文件的位置,可通过context-param加以指定:

    <context-param>
     <param-name>contextConfigLocation</param-name>
     <param-value>/WEB-INF/myApplicationContext.xml</param-value>
    </context-param>

    之后,可以通过

    WebApplicationContextUtils.getWebApplicationContext方法在web应用中获取applicationcontext的引用。

    另外注意不要两种方式都配置上,如果配置了,虽然不会报错,但会导致spring 加载两遍。存在两个BeanFactory 实例。

    这样就会在ContextLoaderListener加载applicationContext.xml时启动定时任务 
    DispatcherServer加载 spring-servlet.xml时也会启动定时任务。相当于加载了两遍bean。

    使用ContextLoaderlistener和DispatcherServlet引入Spring的区别

    1. ContextLoaderListener和DispatcherServlet都会生成一个WebApplicationContext(上下文),分别以不同的name存放在容器中。
    2. 同一个容器里,只允许有一个ContextLoaderListener但是可以用多个DispatcherServlet。 DispatcherServlet的context总是ContextLoaderListener的context的子类。
    3. 在获取bean的时候,会先从DispatcherServlet的context获取,如果没有再从ContextLoaderListener的context获取,这就解释了上面的第一点。
    4. 如果两者用的是同一份配置文件,或者他们的定义bean有交叉就会造成部分bean永远不会被用到(泄漏)。
    5. DispatcherServlet还会加载与SpringMVC相关的bean,如RequestMapping…

    TOmcat、ServerLet解析:

    在TOMCAT启动的时候,自动执行一个SERVLET类,这个类主要作用是生成文件的。 此时我的系统要运行正常,可以做其它的事情。 
    百度了一下, 
    第一步:在web.xml文件中添加[size=medium] 

    Java代码  收藏代码
    1. <servlet>  
    2.     <servlet-name>servlet的名字</servlet-name>  
    3.     <servlet-class>servlet所在的包的路径</servlet-class>  
    4.     <load-on-startup>1</load-on-startup>  
    5.   </servlet>  

    如:

    Java代码  收藏代码
    1. <servlet>  
    2.     <servlet-name>WriteFileServlet</servlet-name>  
    3.     <servlet-class>com.util.WriteFileServlet</servlet-class>  
    4.     <load-on-startup>1</load-on-startup>  
    5.   </servlet>  


    第二步:在WriteFileServlet中进行初始化 

    Java代码  收藏代码
    1. public void init() throws ServletException {  
    2.         // Put your code here   
    3. //前提是把操作的方法封装到了一个类中,然后在这里调用的方法。或者是把操作直接写在这里也可以,但是这种方法不太好。  
    4. }    


    这样就可以在tomcat启动的时候,自动执行这一个servlet了,web.xml是可以包含多个servlet标签的。 
    但是问题来了,只有在tomcat启动完成后用户才可以访问系统,但是此时只有tomcat加载完成servlet中的生成文件的方法后

    ,tomcat才会启动完成,用户才可以访问。也就是不可以用户一边访问系统,后台一边运行servlet生成文件。 

    解决办法是:在servlet中加入多线程,让servlet类实现Runnable接口。把方法放在线程中执行,这样就可以实现用户一边访问系统,后台一边生成文件了。 

  • 相关阅读:
    .Net常见面试题整理(一)——值类型和引用类型
    c#字符串常见操作
    sealed,new,virtual,abstract与override
    c#好的程序员必须掌握的编码习惯
    c#区分传值调用 传引用调用。
    C# const和readonly的区别
    .Net常见面试题整理(二)——装箱和拆箱
    C#Equals()和运算符==的区别
    private,protected,public和internal的区别
    2013应届毕业生“数码视讯”校招应聘总结
  • 原文地址:https://www.cnblogs.com/xiaoyongsz/p/9113782.html
Copyright © 2011-2022 走看看