SpringBoot与Tomcat的启动(内嵌Tomcat)
环境:
SpringBoot 2.0.1
使用SpringBoot开发时,可以通过Maven将工程打成jar包,jar包内嵌Tomcat,这种方式SpringBoot工程将在启动的时候,带动Tomcat的启动,下面分析SpringBoot如何带动Tomcat启动
一个简单的SpringBoot工程启动类
跟进 SpringApplication#run 方法
如果对Spring的启动流程有了解的话,应该知道Spring启动过程中,最重要的就是 AbstractApplicationContext#refresh() 过程,在这个方法中Spring执行了BeanFactory的初始化,Bean的实例化、属性填充、初始化操作等等重要的操作,该方法主要逻辑如下:
仔细观察这个方法,可以发现其中调用了几个空方法,这里应用了 模板模式 ,在 refresh 方法中定义了主干执行流程,并留有空的方法给子类做个性化定制
现在开始,通过debug来看看SpringBoot如何启动Tomcat容器
前面构造 SpringApplicaton 时,已经推断出当前Web工程类型,当开始执行 #run 方法时,会根据不同类型的Web项目创建不同类型的ApplicationContext
创建好 ApplicationContext 之后,看到 refreshContext(context) ,联系本文开头Spring启动的 AbstractApplicationContext#refresh 方法,该方法其实就是触发了后者的执行
执行 refreshContext 方法,来到前面根据 webApplicationType 创建的容器类 ServletWebServerApplicationContext
进入到 TomcatServletWebServerFactory ,可以看到如下启动内置Tomcat的过程
至此,Tomcat继承Spring的 AbstractApplicationContext 类,覆盖它的模板方法 onRefresh ,SpringBoot在自身启动的过程中,启动了内置的Tomcat服务器
从零开始新建Springboot项目之项目启动(一)
一般都是使用搭建好的框架进行业务逻辑开发,一直不清楚整个项目是如何从零到一构建出来的。所以开一个帖子,记录一下一个springboot项目是如何构建的。
使用的工具为idea
选择maven或者spring initializr都可以。spring initializr会在pom中自动添加一些springboot用到的jar包,此处选择maven。起好名字后,一路next即可
从实际开发角度,构建Module不是必选项。但学习嘛,还是要知道是怎么创建的
右键项目名称 -》 New -》 Module
依然选择maven,起名字即可。一般命名为:XXXX-Controller,XXXX-Service等等
建好后,pom中会多出以下内容
(放弃多模块配置)
可在此处搜索 mvnrepository
首先添加parent,作为父级依赖。位置在 《project》《/project》 的下一级,与 《groupId》org.example《/groupId》 同级,
在 《parent》《/parent》 同级新建 《dependency》《/dependency》 标签,引入web项目需要的依赖
如果是多模块的项目,需要在每一个模块的pom文件中,添加其依赖的其他模块。例如controller依赖service,则需要在controller的pom文件中添加以下依赖信息。如果不是多模块项目,可以忽略
在java路径下新建顶级路径 com.tardis ,在此路径下新建文件 CustomerApplication (名字随意)。新建 controller , service 的 package 。在 CustomerApplication 添加如下方法
文件的层级关系如图
在 resource 目录下,新建 application.yml , application.dev.yml , application.prod.yml 文件,作为总体,开发环境,生产环境的配置文件。配置文件格式为 properties , yml 均可,此处使用 yml ,看起来比较简洁清晰
层级关系如图
为了更好地演示效果,可以先写一个简单的Controller进行测试,在controller文件夹中新建class,名字随意。文件层级如图。放一个最简单的接口。
使用postman调用,返回结果如下
springboot启动报错可以测试吗
可以,springboot启动报错一般可以通过以下步骤进行测试:
1、查看错误日志,从而确定错误的原因,比如配置错误、依赖不兼容等。
2、检查和修复 springboot 应用的配置,比如检查配置文件的配置是否正确,检查依赖的版本是否兼容,确保springboot应用正确运行。
3、检查springboot应用的启动类,确保启动类没有编写错误,保证springboot应用可以正常启动。
4、检查springboot应用的主类,确保主类没有编写错误,保证springboot应用可以正常运行。
5、在测试环境中运行springboot应用,比如使用maven命令运行springboot应用,以便及时发现错误并进行修复。
6、检查项目的资源文件,确保资源文件的引用方式正确,保证springboot应用的功能可以正常使用。
SpringBoot项目启动出现required a bean of type ’XXX’ that could not be found
在对Controller进行修改完的时候,启动项目出现的问题,情况如图所示:
对于这个问题,总结分析原因如下:
也就是Bean配置失败
删除一些类的时候,注意将这些类连带的@Autowired注解一起删掉,不然可能没有报错,但导致无法注入Bean,出现这种不明所以的bug,就可以解决。
仔细检查类的路径是不是正确,因为在spring boot启动时启动类会自动扫描发现所在包及其子包下的内容,例如出现错将Service的包放在了启动类的所在包的外层,导致启动时扫描不到就会报错。解决办法就是将包结构重新整理。
解决方法 是在dao层的UserMapper上加上 @Mapper ,大部分问题都是由于缺少这个持久层注解问题
持久层 DAO 和业务层 Service 的包都必须是在主程序的包的子包下面才会注入。在持久层里面的Dao接口中应当以 @Mapper 进行注解,在业务层的Servcie类中应当以 @Service 进行注解
Spring Boot启动速度慢的原因总结
现在spring boot的架构可以说是非常流行,不会你都不好意思说你是做java的。可是它火归火,也有一些小问题需要咱们去注意。
如果是单体项目,并且在启动速度方面没有任何要求,那么请忽略。
下面进入主题,在什么情况下spring boot的项目启动会变慢呢
启动项目的机器硬件配置不能拖后腿,否则你说项目启动慢,项目还觉得机器不行呢…
比如网络,内存大小,CPU核心数等,不要求太高,至少也要够用吧
抛开各种人为因素,例如各种连接时间较长,其他组件启动较慢导致等待…
项目中使用的无用配置太多 。例如在一个最简单的web中,你还加入了其他各种maven配置,并且将他们配置到项目中(只是比较夸张的例子,这些配置加入都不用),然后项目本身也不懂,既然你配置了,那就加载呗。一个花0.1秒,10个就1秒,100个就10秒了…以此类推,这一点就是最容易想明白的地方了。
spring boot的自动配置 。自动配置是spring boot的一个特色,但是也是它启动慢的一个弊病。没办法,通常好用功能全的东西,总会在一些地方上有缺陷。上面说到无用的配置多,这里要说的就是spring boot它自己装配的东西太多。你可以看到在spring boot的相关jar包里,都存放着spring.factories的文件,进去一看,大部分都是写了很多的类,它是实现spring boot自动装配的核心之一。但是你仔细观察会发现,其实有很多类,你可能完全不用。但有什么办法呢,不管你用不用,至少它都会给你检查一遍,这不也是花时间的地方吗?
项目精简程度不够 。现在比较流行微服务的概念,我认为它的概念核心含义即为精简,单一,并且多数需要强调启动速度的地方也多是出自微服务的项目中。一个微服务项目中,最好是在10秒以内能够启动完毕。但是多数是做不到的,原因在于项目拆分的还不够细。你说一个接口启动快,还是10个快,或是更多,答案很明显。很多项目做到了大而全,所谓大而全就是功能很多,配置很齐全,各种可以扩展配置等,全面的不行不行的,但这意味着什么,你的配置多,有用没用先不管,至少需要编译和加载的类文件都会多出很多来,你说要这样的项目能启动快,怎么能启动快呢?
此次分享就到这里,欢迎大家的讨论。
SpringBoot的启动过程及部分注解
相比于以前繁琐的基于 Spring 的 Web 应用,SpringBoot 通过默认配置很多框架的方式,极大的简化了项目的搭建以及开发流程。
一个简单的 SpringBoot 应用只需要三步:
1.在 pom.xml 中引入所需要的依赖
2.在 application.yml 配置所需的数据源
3.在启动类中加入 @SpringBootApplication 注解 以及 run 方法
启动流程
1.SpringApplication.run()启动
2.新建 SpringApplication 实例,主要是初始化一些成员变量,参数列表等
prepareContext():
refreshContext() 中 refresh():
核心注解(部分)
@SpringBootAppliction 启动类
@Configuration + @EnableAutoConfiguration + @ComponentScan
@Configuration
允许在应用上下文中注册其它的 bean,可用 @Component代替
@Configuration 会为 bean 创建一个代理类,这个类会拦截所有被 @Bean 修饰的方法,从容器中返回所需要的单例对象;@Component 不会创建代理类,会直接执行方法,每次返回一个新的对象
@EnableAutoConfiguration
启用 springboot 自动装配,该参数位于 spring.factories 中 org.springframework.boot.autoconfigure.EnableAutoConfiguration
@ComponentScan
扫描被@Component (@Service,@Controller)注解的 bean,注解默认会扫描该类所在的包下所有的类
@Autowired
自动导入对象到类中,被注入进的类被 Spring 容器管理 Service-》Controller
@Component
通用的注解,可标注任意类为 Spring 组件
@Repository 持久层
@Service 服务层
@Controller 控制层
@Bean
用于告诉方法产生一个 Bean 对象,然后这个对象交给 IOC 容器管理。产生这个Bean对象的方法Spring只会调用一次,然后将这个Bean对象放在 IOC 容器中
spring-boot 项目启动过慢问题
问题表现
最近手上一个基于 spring-boot 开发的系统在阿里云的 ECS 上(ubuntu 14.04)启动过程中碰到启动时间过长问题,表现如下,启动日志长时间处于一下状态:
即系统会卡在:
这句日志上长达十分钟以上。
分析流程如下
解决方案
根据上述文章,可以修改系统属性将Spring Boot的嵌入式Tomcat实例配置为使用 /dev/urandom 来生成随机来解决这个问题。具体操作如下,在 .bashrc 中添加如下的环境变量。
执行 source .bashrc 即可。
重新启动系统,上述问题解决
参考文章 :
springboot怎么启动项目
1、main方法启动
2、打包成jar,然后java -jar xxx.jar
3、mvn spring-boot:run
详细的说明请参照:java学习-Spring-boot启动方式有哪些?
希望能够解决您的问题,望君采纳
SpringBoot项目启动报错,端口被占用
1.根据端口号查找当前进程的pid
cmd打开命令窗口
输入命令:netstat -ano|findstr 8094(8094 为端口号)
如图2-01 27488为端口8094对应进程的pid
2.根据pid杀掉进程
继续输入命令:taskkill /f /t /pid 27488(27488为进程pid)
3.看到 如图2-02 说明就已经成功终止进程。
springboot项目打war包,开机自启动
那么如果想要开机之后,项目自动运行起来要怎么做呢?
1.在pom.xml中添加依赖
2.右击下图鼠标选中区域,点击 “publish”发布一下项目
3.点击maven install打包
4.点击完之后,控制台开始执行,当我们看到BUILD SUCCESS那么就成功啦
7.将项目名.war这个文件ctrl+c拷贝一下,到D盘的根目录去粘贴一下(可以重命名)
9.再次打开记事本,在d盘创建一个文本文件(命名为startup.vbs)扩展名将txt改为vbs
功能:隐藏上一个bat的黑窗口的。否则只要关闭黑窗口项目就会结束。运行startup.vbs之后会隐藏黑窗口。
在开始菜单中,右击启动,打开,将刚才创建的vbs,生成一个快捷方式拖进去
然后重启就可以自动启动啦!
需要注意的地方就是:因为之前在tomcat上面部署,然后去打开项目在浏览器地址输入的是这样的,因为我的tomcat端口设置的是80,所以可隐藏不写 ,如图,但是可以看到,发现并没有进去。