spring mvc框架 类初始化2次 解决过程
2016-03-17 00:00
375 查看
背景:刚开始做平台的工作,接触的就是spring mvc框架,struts没碰过,没有任何java web的理论基础,项目组的这个项目框架是spring mvc + ibatis组合的。
做了一个项目觉得挺顺手,都是小项目,第一个项目还有人稍微指导,第二个项目之后都靠自己做了。有空的时候会稍微改一下这个框架的基础东西,比如说,去掉一堆没用的jar包,冗余太多,部署上传费时。去掉struts相关的包,最后在没有提示错误时,通过报的异常导入包,去掉了几十个无用的,方法很土。
事情起因:因为要用到消息队列,另一个同事调试时,发现本来应该是3个消息队列,却可以看到6个,怀疑类初始化2次,写了个简单的方法,测试,可以看到2次初始化。我自己也写了个,确实看到输出2次。
解决过程:经过调查,发现spring的配置文件中有2处component-scan,配置文件(web.xml,applicationContext.xml,spring-servlet.xml)大概如下:
web.xml
applicationContext.xml
spring-servlet.xml
当我删掉applicationContext.xml里的<context:component-scan base-package="com.test" />时,发现程序正常运行,将配置修改到另外一个项目里,出问题了,提示大概是找不到定时器的bean。还原回来,删掉spring-servlet.xml里的<context:component-scan base-package="com.test" />,运行项目,发现所有的url-mapping都失效了。
之后因为不想让消息队列初始化2次,就把spring-servlet.xml的<context:component-scan base-package="com.test" />改为<context:component-scan base-package="com.test.xxx.*.controller" />,使初始2次的bean缩小范围。
这几天稍微看了一下spring mvc相关的资料,下午试了一下,把applicationContext.xml的<context:component-scan base-package="com.test" />去掉,并且把定时器配置相关的<import resource="classpath:app-scheduling.xml"/>移到spring-servlet.xml中,就ok了,定时器正常执行,网址映射正常。
事后心得:看来做项目还是要学一些基础理论的。
==============================================
2017-8-4补充
最近看到beetlsql的Spring+beetlsql例子的配置文件,发现了一个彻底解决的办法。web.xml文件都不用修改,主要改的就是applicationContext.xml和spring-servlet.xml,把所有spring-servlet.xml的配置内容都移入applicationContext.xml,spring-servlet.xml留一个空壳就可以了。
spring-servlet.xml
applicationContext.xml
做了一个项目觉得挺顺手,都是小项目,第一个项目还有人稍微指导,第二个项目之后都靠自己做了。有空的时候会稍微改一下这个框架的基础东西,比如说,去掉一堆没用的jar包,冗余太多,部署上传费时。去掉struts相关的包,最后在没有提示错误时,通过报的异常导入包,去掉了几十个无用的,方法很土。
事情起因:因为要用到消息队列,另一个同事调试时,发现本来应该是3个消息队列,却可以看到6个,怀疑类初始化2次,写了个简单的方法,测试,可以看到2次初始化。我自己也写了个,确实看到输出2次。
@Service("Test") public class Test { private static int cnt = 0; public Test() { super(); System.out.println("cnt = " + cnt); cnt++; } }
解决过程:经过调查,发现spring的配置文件中有2处component-scan,配置文件(web.xml,applicationContext.xml,spring-servlet.xml)大概如下:
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <!--定义日志配置文件--> <context-param> <param-name>log4jConfigLocation</param-name> <param-value>/WEB-INF/classes/log4j.properties</param-value> </context-param> <!-- 配置spring配置文件路径 ,webservice配置文件路径 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/classes/applicationContext.xml; </param-value> </context-param> <!-- Spring Listener Config --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- url配置为/,不带文件后缀,会造成其它静态文件(js,css等)不能访问。如配为*.do(*.html),则不影响静态文件的访问。--> <servlet> <servlet-name>spring</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>namespace</param-name> <param-value>/classes/spring-servlet</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>spring</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> <!-- 编码(UTF-8)转换过滤器 --> <filter> <filter-name>Set Character Encoding</filter-name> <filter-class> com.test.xxx.filter.SetCharacterEncodingFilter </filter-class> </filter> <filter-mapping> <filter-name>Set Character Encoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- filter.listener,servlet,and servlet-mapping等元素要在session-config之前,这里设置的时间单位是分钟 --> <session-config> <session-timeout>25</session-timeout> </session-config> </web-app>
applicationContext.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:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <!-- ORACLE数据源配置 --> <bean id="DataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <!-- 数据库配置省略 --> </bean> <!-- 整合ibatis --> <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"> <property name="dataSource"> <ref local="DataSource" /> </property> <property name="configLocations"> <value>classpath:SqlMapConfig.xml</value> </property> </bean> <!-- 自动注入实现类装填 --> <context:component-scan base-package="com.test" /> <context:annotation-config /> <!-- 配置事务管理 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource"> <ref local="DataSource" /> </property> </bean> <!-- 定义SERVICE事务通知 --> <tx:advice id="txAdvice_service" transaction-manager="transactionManager"> <!-- 定义方法的过滤规则 --> <tx:attributes> <!-- 所有方法都使用事务 --> <tx:method name="*" propagation="REQUIRED"/> <!-- 定义所有get开头的方法都是只读的 --> <tx:method name="get*" read-only="true"/> </tx:attributes> </tx:advice> <!-- 定义AOP配置 --> <aop:config proxy-target-class="true"> <!-- 适配切入点(service)和事务的通知 --> <aop:advisor pointcut="execution(* *..service..impl..*.*(..))" advice-ref="txAdvice_service" /> </aop:config> <import resource="classpath:app-scheduling.xml"/> </beans>
spring-servlet.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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> <!-- 把标记了@Controller注解的类转换为bean --> <context:component-scan base-package="com.test" /> <!-- 在SpringMVC中使用JSON必须配置 --> <mvc:annotation-driven /> <!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 --> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" /> <!-- 对模型视图名称的解析,即在模型视图名称添加前后缀 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/view/" p:suffix=".jsp" /> </beans>
当我删掉applicationContext.xml里的<context:component-scan base-package="com.test" />时,发现程序正常运行,将配置修改到另外一个项目里,出问题了,提示大概是找不到定时器的bean。还原回来,删掉spring-servlet.xml里的<context:component-scan base-package="com.test" />,运行项目,发现所有的url-mapping都失效了。
之后因为不想让消息队列初始化2次,就把spring-servlet.xml的<context:component-scan base-package="com.test" />改为<context:component-scan base-package="com.test.xxx.*.controller" />,使初始2次的bean缩小范围。
这几天稍微看了一下spring mvc相关的资料,下午试了一下,把applicationContext.xml的<context:component-scan base-package="com.test" />去掉,并且把定时器配置相关的<import resource="classpath:app-scheduling.xml"/>移到spring-servlet.xml中,就ok了,定时器正常执行,网址映射正常。
事后心得:看来做项目还是要学一些基础理论的。
==============================================
2017-8-4补充
最近看到beetlsql的Spring+beetlsql例子的配置文件,发现了一个彻底解决的办法。web.xml文件都不用修改,主要改的就是applicationContext.xml和spring-servlet.xml,把所有spring-servlet.xml的配置内容都移入applicationContext.xml,spring-servlet.xml留一个空壳就可以了。
spring-servlet.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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> </beans>
applicationContext.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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <!-- 把标记了@Controller注解的类转换为bean --> <context:component-scan base-package="com.test" /> <!-- 在SpringMVC中使用JSON必须配置 --> <mvc:annotation-driven /> <!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 --> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" /> <!-- 对模型视图名称的解析,即在模型视图名称添加前后缀 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/view/" p:suffix=".jsp" /> <!-- ORACLE数据源配置 --> <bean id="DataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <!-- 数据库配置省略 --> </bean> <!-- 整合ibatis --> <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"> <property name="dataSource"> <ref local="DataSource" /> </property> <property name="configLocations"> <value>classpath:SqlMapConfig.xml</value> </property> </bean> <!-- 自动注入实现类装填 --> <context:component-scan base-package="com.test" /> <context:annotation-config /> <!-- 配置事务管理 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource"> <ref local="DataSource" /> </property> </bean> <!-- 定义SERVICE事务通知 --> <tx:advice id="txAdvice_service" transaction-manager="transactionManager"> <!-- 定义方法的过滤规则 --> <tx:attributes> <!-- 所有方法都使用事务 --> <tx:method name="*" propagation="REQUIRED"/> <!-- 定义所有get开头的方法都是只读的 --> <tx:method name="get*" read-only="true"/> </tx:attributes> </tx:advice> <!-- 定义AOP配置 --> <aop:config proxy-target-class="true"> <!-- 适配切入点(service)和事务的通知 --> <aop:advisor pointcut="execution(* *..service..impl..*.*(..))" advice-ref="txAdvice_service" /> </aop:config> <import resource="classpath:app-scheduling.xml"/> </beans>
相关文章推荐
- 分享微信开发Html5轻游戏中的几个坑
- 一个jar包里的网站
- 一个jar包里的网站之文件上传
- 一个jar包里的网站之返回对媒体类型
- [游戏资讯]《极品飞车16:亡命狂飙》配置需求公布
- 配置文件神器 typesafe conf 用法简介
- Spring整合Quartz(JobDetailBean方式)
- 配置文件神器 typesafe conf 用法简介
- Spring整合Quartz(JobDetailBean方式)
- 路由器备份配置
- 路由器的基本配置
- 路由器基础配置及传输协议
- 经典配置 Vlan篇
- 备份线路的配置
- 插件管理框架 for Delphi(一)
- 交换机如何配置 新手配置交换机详细教程
- 如何进行系统配置
- 路由器的配置与调试
- DOS下内存的配置