• springmvc项目中InitializingBean执行2次


    为了修复生产数据,需要执行一段一次性的代码。 鉴于是spring老项目,就想到了InitializingBean。

    代码如下。服务启动后,log里发现出现2条“一次性任务开始”。 好在里面逻辑做了防重控制,没有受到什么影响。

    @Slf4j
    @Component
    public class TransToBankBean implements InitializingBean {
        @Autowired
        private FixedLdysZhOrdersService xxxService;
    
        @Override
        public synchronized void afterPropertiesSet() {
            log.info("一次性任务开始");
            ....
        }
    }

    今天理了一下程序配置。发现web.xml配置有问题。

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
    
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml,classpath:spring-mybatis.xml,classpath:spring-dubbo.xml</param-value>
        </context-param>
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        <listener>
            <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
        </listener>
        <servlet>
            <servlet-name>SpringMVC</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:spring-mvc.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
            <async-supported>true</async-supported>
        </servlet>
        <servlet-mapping>
            <servlet-name>SpringMVC</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
        <welcome-file-list>
            <welcome-file>/index.jsp</welcome-file>
        </welcome-file-list>
    </web-app>

    注意到上面web.xml中有两个contextConfigLocation, 一个位于context-param参数中, 另一个位于servelt的init-param参数中。

    问题就出现在这个contextConfigLocation上。

    contextConfigLocation,名如其义,指的是context配置(文件)的位置。
    servelt/init-param的contextConfig是为了加载DispatcherServlet的, 而context-param的contextConfig是为了加载web程序需要加载的数据库等等配置。

    再来说说servlet节点配置:
    servlet有这么几个属性:servlet-name、servlet-class、init-param。其中,servlet-class通常就是我们熟知的 DispatcherServlet。init-param中可以指定contextConfigLocation。
    1) init-param里如果未配置contextConfigLocation,则要求程序在WEB-INF存在名为[servlet-name]-servlet.xml的配置文件,否则程序启动会报异常:java.io.FileNotFoundException:Could not open ServletContext resource [/WEB-INF/SpringMVC-servlet.xml] 。(注意:我这里servlet-name的值是SpringMVC,所以文件名字会是 SpringMVC-servlet.xml)
    2) init-param里如果有contextConfigLocation配置,则DispatcherServlet会使用这个指定的配置文件作为配置。例如,我指定的参数值是classpath:spring-mvc.xml, 这个文件定义在main/resources下,编译后存在于程序包的classes目录中。

    显然,上面web.xml中两个contextConfigLocation都指定了spring-mvc.xml。这个context文件里指定了component-scan包扫描路径。
    上面定义的InitializingBean实现类就在这些package下面。所以,不难理解,这个类所覆写的afterPropertiesSet会被执行两次。


    好,了解了上面的解释。那么,我们就知道该怎么改了。------>分离配置,解决扫描两遍的问题。
    改造后的web.xml如下, 两处contextConfigLocation分别指定的是application-context.xml 和 spring-mvc.xml。两者各司其职 -----> application-context.xml是spring应用程序的上下文配置,不含springmvc配置; spring-mvc.xml中只有springmvc配置。

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
    
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:application-context.xml</param-value>
        </context-param>
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        <listener>
            <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
        </listener>
        <servlet>
            <servlet-name>SpringMVC</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:spring-mvc.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
            <async-supported>true</async-supported>
        </servlet>
        <servlet-mapping>
            <servlet-name>SpringMVC</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
        <welcome-file-list>
            <welcome-file>/index.jsp</welcome-file>
        </welcome-file-list>
    </web-app>

     spring-mvc.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    
        <!-- 扩充了注解驱动,可以将请求参数绑定到控制器参数 -->
        <mvc:annotation-driven/>
    
        <mvc:default-servlet-handler/>
    
        <!--    controller所在包-->
        <context:component-scan base-package="com.levy.rpcprovider.controller"/>
    
    </beans>
  • 相关阅读:
    Resin4 自定义端口
    设备系统识别,解决方案。
    Reactjs-JQuery-Vuejs-Extjs-Angularjs对比
    HTML页面的加载
    传输层协议TCP和UDP
    常用的14种HTTP状态码速查手册
    前端总结·基础篇·CSS(二)视觉
    前端总结·基础篇·CSS(一)布局
    AngularJS 中的Promise --- $q服务详解
    ngRoute 和 ui.router 的使用方法和区别
  • 原文地址:https://www.cnblogs.com/buguge/p/16286630.html
Copyright © 2020-2023  润新知