项目就启动了两次,程序倒是正常运行,关键我里边写了个while 循环,不能让它启动两次啊

百度了一下,有人说是tomcat server.xml或者tomcat新建服务的时候设置出了问题 ....最终发现不是这里问题,下文有最终问题所在,解决问题过程是我一步步理了理tomcat的启动,加载配置文件.可谓是一步不理解 的系统,无法解决问题

存在上边的问题, tomcat 是一方面,web.xml配置是另一个问题所在, 如果是按照默认的那种方式加上的tomcat server ,tomcat的问题就不用找了.如果是修改了项目自动部署到tomcat这块那就可能是tomcat的问题了

这里有tomcat server.xml 一篇文章详细介绍了 其中的参数说明,仔细看看,相信会排查出是否跟tomcat有关了https://www.cnblogs.com/kismetv/p/7228274.html#title1 写的很好.

总结一下就是,默认 eclipse 加载了tomcat 并没有使用tomcat 安装目录的webapps,打开项目里边servers 下的server.xml .

这个文件是tomcat 当前项目用到环境用到的server.xml,这个文件是从安装目录的server.xml 加过来的,右键属性可以看到当前所在的目录

这个目录是在哪订的呢看下图 ,双击server栏目下当前的server.红框内就是当前项目制定的server目录 配置文件path.

configuration path 就是这个目录

默认选第一个没问题 ,第二个为tomcat 的安装目录这个配置是将项目发布到tomcat的webapps下。

在servers试图启动Tomcat后,调用的是tomcat所在目录的执行文件,除了部署eclipse下的项目,tomcat还要加载webapps下的所有项目,所以就重复加载了。

那是配置文件里边host 里边的配置出现问题

错误配置:

<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false"> <Context docBase="/usr/local/apache-tomcat-6.0.29/webapps/XXX"
path="" reloadable="true"></Context>
<Context docBase="/usr/local/apache-tomcat-6.0.29/webapps/XXX"
path="/admin" reloadable="true"></Context>
</Host>

以上配置,由于host节点配置了appBase为webapps,所有tomcat会加载webapps里的所有项目,下面又配置了webapps里的项目,导致项目又加载一次,所以会导致项目重复加载,定时程序会在几秒之内重复执行,后来改了一下配置好了,

如下正确配置:

<Host name="localhost" appBase="" unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false"> <Context docBase="/usr/local/apache-tomcat-6.0.29/webapps/XXX"
path="" reloadable="true"></Context>
<Context docBase="/usr/local/apache-tomcat-6.0.29/webapps/XXX"
path="/admin" reloadable="true"></Context>
</Host>
<Host name="localhost" appBase="webapps" 这个appBase 默认是找tomcat 安装目录下的webapps ,因为eclipse 改了个项目部署路径为下图:

部署路径为上图中tmp2 不同项目可能是tmp1 ,下的wtpwebapps 下边,war文件解压后的项目路径相同的文件.
接上既然eclipse已经默认设置了这个路径.,那tomcat server.xml 里边的host 内的webapps 在此是不作数的. 上文有个server.xml介绍的文章里已经说明,如果部署路径不在webapps内,要在
 <Context docBase= 内指定,那我们看看部署后eclipse 自动加了一行context,这是原先tomcat下的server.xml 没有的,于是乎 启动项目就能正常加载我们自己的项目了...所以只要不是自己指定的部署路径,默认的eclipse的server.xml不存在问题.当然还有一些配置域名的需求的可以参考上边
出现的问题.
  <Context docBase="AppService" path="/AppService" reloadable="true" source="org.eclipse.jst.jee.server:AppService"/></Host>

以上就是会出现百度上别人所说 的配置问题导致的两次启动.而这种声音压过了spring 和springmvc 两个配置文件中的问题.

看web.xml 文件里的一个配置

  <servlet>
<servlet-name>applicationContext</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-common.xml</param-value>
</init-param>
<load-on-startup></load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>applicationContext</servlet-name>
<url-pattern>/</url-pattern>
<url-pattern>*.json</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-common.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-common.xml</param-value>
</init-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-common.xml</param-value>
</context-param>
内 <param-value>classpath:spring-common.xml</param-value> 相同
结果就这么悲剧了
<context-param> 是spring 加载的配置文件
<init-param> 是springmvc 加载的配置文件 .这两者是分开加载的,起先是混为一谈了. 别人的配置的运行的正常也没在意
通过把上边的<init-param> 注释掉,程序确实加载了一次,提示找不到...xml配置文件.所以不能注释掉.
把 <param-value> 和<context-param> 的配置文件分开吧,总之都需要配置,另一个spring 的建一个空文件挂上去.问题解决.后期如果有配置项也 可以放在spring指定的配置文件里.
正确的配置
  <context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
<!-- <param-value>classpath:spring-common.xml</param-value> -->
</context-param>

于是声势浩荡的项目启动两次的问题最终解决.....

等等...问题还没解决...这里还有spring 和springmvc两个容器加载bean 的问题, springmvc是spring 的子容器,加了控制器,如下图

所以spring的配置文件不能为空.....如果所有配置都在一个文件里, 那肯定是不行了,

一、Spring和SpringMVC的父子容器关系

1.讲问题之前要先明白一个关系

一般来说,我们在整合spring和SpringMVC这两个框架中,web.xml会这样写到:

<!-- 加载spring容器 -->
<!-- 初始化加载application.xml的各种配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/application-*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- 配置springmvc前端控制器 -->
<servlet>
<servlet-name>taotao-manager</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- contextConfigLocation不是必须的, 如果不配置contextConfigLocation,
springmvc的配置文件默认在:WEB-INF/servlet的name+"-servlet.xml" -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
首先配置的是Spring容器的初始化加载的application文件,然后是SpringMVC的前端控制器(DispatchServlet),当配置完DispatchServlet后会在Spring容器中创建一个新的容器。其实这是两个容器,Spring作为父容器,SpringMVC作为子容器。
让我们用图来看一下这个父子关系的原理:

平时我们在项目中注入关系是这样的顺序(结合图来说):在Service中注入Dao(初始化自动注入,利用@Autowired),接着在Controller里注入Service(初始化自动注入,利用@Autowired),看图,这就意味这作为SpringMVC的子容器是可以访问父容器Spring对象的。

那么问大家一个问题。要是反过来呢,你把Controller注入到Service中能行么?
肯定是不行的啊!(如图,这也说明了父容器是不能调用子容器对象的)

如果Dao,Serive,Controller要是都在Spring容器中,无疑上边的问题是肯定的,因为都是在一个bean里,一个容器中。

2.问题:为什么不能在Spring中的Service层配置全局扫描?

例如:一个项目中我总项目的名字叫com.shop,我们在配置applicationContext-service.xml中,包扫描代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
...../ 此处省略>

<!-- 扫描包Service实现类 -->
<context:component-scan base-package="com.shop.service"></context:component-scan>
</beans>
上面所配置的是一个局部扫描,而不是全局扫描。接下来说原因:
这里就和上面讲到的父子容器有关系,假设我们做了全局扫描那么代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
...../ 此处省略>

<!-- 扫描包Service实现类 -->
<context:component-scan base-package="com.shop"></context:component-scan>
</beans>
此时的Spring容器中就会扫描到@Controller,@Service,@Reposity,@Component,此时的图如下:

结合图去看,相当于他们都会放到大的容器中,而这时的SpringMVC容器中没有对象,没有对象就没有Controller,所以加载处理器,适配器的时候就会找不到映射对象,映射关系,因此在页面上就会出现404的错误。

3.如果不用Spring容器,直接把所有层放入SpringMVC容器中可不可以?

当然可以,如果没有Spring容器,我们是可以把所有层放入SpringMVC的。单独使用这个容器是完全可以的,而且是轻量级的。就是直接把所有的层次关系都放到了SpringMVC中,并没有用到Spring容器。

4.那么为什么我们在项目中还要联合用到Spring容器和SpringMVC容器?

答案是:Spring的扩展性,如果要是项目需要加入Struts等可以整合进来,便于扩展框架。如果要是为了快,为了方便开发,完全可以用SpringMVC框架。

5.结论

如果在项目中我们在Service层做全局包扫描,那么springmvc不能提供服务,因为springmvc子容器中没有controller对象。

爬坑记-tomcat 项目启动两次的的解决的更多相关文章

  1. Linux下Tomcat项目启动报错

    Linux下Tomcat项目启动报错 org.springframework.beans.factory.CannotLoadBeanClassException: Error loading cla ...

  2. MyEclipse环境的项目改为在Eclipse中运行爬坑记【我】

      新检出一个web项目,同事都是运行在MyEclipse中的,我用Eclipse启动, 1.首先是许多jar包报错: 处理方法为 remove掉,然后 选 WEB-INF 下的所有 jar 重新添加 ...

  3. .NET Core爬坑记 1.0 项目文件

    前言: 之所以要写这个系列是因为在移植项目到ASP.NET Core平台的过程中,遇到了一些“新变化”,这些变化有编译方面的.有API方面的,今天要讲的是编译方面的一些问题.我把它们整理后分享出来,以 ...

  4. mac开发环境爬坑记(搭建php+nginx+mysql+redis+laravel+git+phpstorm)

    题外话:前几天,终于以原价一半的价格,将我那台15版mbp在bbs上卖了出去.之所以用了“终于”这个词儿,是我一直迟迟没有下定决心卖掉它,可眼瞅着再不卖掉,又要掉价,况且我的新电脑,也终于下来了. 话 ...

  5. mint-ui之picker爬坑记

    picker的数据来源为动态获取时,数据无法正常渲染!因为方法不对,所以坑大了!深刻地体会到'业不精,我之过',谨以此文,深刻地记录一下踩坑及爬坑的整个过程,以便日后不再入坑,也给后来者提供一下参考 ...

  6. 新检出普通web项目爬坑记【我】

    新检出一个普通 web项目, 1.首先发现需要用到的一些代码包没有加到构建目录, 先加入构建: 2.然后发现项目大面积报错, 随便打开代码看下,发现是因为缺少jar包,因为报错的代码太多了,所以使用 ...

  7. maven项目新检出后不编译爬坑记 及 mvn clean package报错 WagonTransporterFactory: java.util.NoSuchElementException 异常【我】

    从SVN新检出一个maven项目,配置好后,发现项目无法编译(只有一个test包中的代码显示编译报错,其他所有包中的代码都不编译,也不报错), 先注释掉报错的test包中的所有内容, 用Eclipse ...

  8. centos部署yapi爬坑记

    前言 这几天终于完成了为期三个月的公司某个demo版的项目,在这期间和公司的后台因为API的事怼过无数次了,'我的接口没问题,是你请求的方式不对吧!'.'一定是你请求的参数不对'......诸如此类问 ...

  9. SQL Server 事务复制爬坑记

    SQL Server 复制功能折腾了好几天了,现特将其配置过程以及其间遇到的问题记录下来,以备日后查阅.同时,也让“同道”同学们少走不必要的弯路.如果有不对之处,欢迎大家指正,欢迎沟通交流. 一.复制 ...

随机推荐

  1. debian apache2 修改默认路径

    1.修改 /etc/apache2/sites-enable/000-default.conf 将DocumentRoot改成你的路径 2.修改 /etc/apache2/apache2.conf & ...

  2. java 日志脱敏框架 sensitive,优雅的打印脱敏日志

    问题 为了保证用户的信息安全,敏感信息需要脱敏. 项目开发过程中,每次处理敏感信息的日志问题感觉很麻烦,大部分都是用工具类单独处理,不利于以后统一管理,很不优雅. 于是,就写了一个基于 java 注解 ...

  3. 常用LINUX命令汇总

    一.基本命令bash Bash(GNU Bourne-Again Shell)是许多Linux平台的内定Shellpwd 查看当前所在目录ls 查看目录内所有文件cd 进入目录cd .. 返回上一层p ...

  4. Linux下查看tomcat版本

    进入到tomcat的bin目录下,再执行./version.sh tomcat版本:7.0

  5. LeetCode 100. Same Tree 判断两棵二叉树是否相等 C++

    Given two binary trees, write a function to check if they are the same or not. Two binary trees are ...

  6. HTTPS 基本流程3

    前文说到了6 组key material, 12个hash 值,非常迷惑, 今天才搞明白, 原来所有这些内容就是 对称密钥的内容. 上面的图 虽然不是很清晰,但是, 其实也已经写明白了, 就是 右边的 ...

  7. Exp2 后门原理与实践 - 20164304 姜奥

    实验内容  (1)使用netcat获取主机操作Shell,cron启动 (2)使用socat获取主机操作Shell, 任务计划启动 (3)使用MSF meterpreter(或其他软件)生成可执行文件 ...

  8. 40_redux_counter应用_redux完善版本

    项目结构: 代码: import React from 'react'; import ReactDOM from 'react-dom'; import store from './redux/st ...

  9. js:上传图片并预览(https://blog.csdn.net/weixin_38023551/article/details/78318532)

    1: //filereader 的方法<form action="" enctype="multipart/form-data"> <inpu ...

  10. 云栖大会day1 上午

    参与云栖大会第一天感受 早晨参与内容 数据智能实践专场 议程是 09:00-09:25 互联网下半场用户增长之路 吕志国 [友盟+]CPO 09:25-09:50 数据开启智慧零售的升级引擎 刘延明 ...