微服务阶段
javase:OOP
mysql:数据持久化
html+css+js+jquery+框架:视图,框架不熟练,css不好;
javaweb:独立开发MVC三层架构的网站:原始
ssm:框架,简化了我们的框架,配置也开始较为复杂;wai包:tomcat运行
spring再简化:Springboot 微服务架构!使用jar包,内嵌tomcat
之后服务越来越多:使用springcloud
学习内容
springboot:大致介绍
是什么
配置如何编写,使用ymal
自动配置原理:重要,谈资
集成web开发,业务的核心
集成数据库,例如JDBC、Druid、Mybatis
swagger:接口文档
异步任务,邮件发送,任务调度
SpringSecurity,shiro
分布式开发:Dubbo(RPC)+zookeeper
springcloud
微服务
springcloud入门
Restful
Eureka
Nginx,负载均衡
Ribbon
Feign
HyStrix:
Zuul路由网关
SpringCloud config:git
一、springboot快速入门
1、什么是spring
Spring是一个开源框架,2003年兴起的轻量级Java开发框架,Sprng是为了解决企业及应用开发的复杂性而创建的,简化开发。
基于Pojo的轻量级和最小侵入式编程
通过IOC,依赖注入(DI)和面向接口实现松耦合
基于切面(AOP)和惯例进行声明式编程
通过切面和模板样式代码
2、什么是SpringBoot
springboot取代了ssm中的ss角色
javaweb-> struts -> springmvc,其中structs很多的请求是.do结尾的。之后出来springboot主流微服务的,甚至现在出来了新服务架构:服务网格。
Springboot就是一个javaweb的开发框架,和springmvc类似,对比其他javaweb框架好处,更加简化开发,约定大于配置,迅速开发web应用,几行代码就能开发一个http接口。
能够默认帮我们进行很多设置,多数springboot应用只需要很少的Spring配置。同时集成了大量的第三方库配置(Redis、MongoDB、Jpa、RabbitMQ、Quartz等),这些第三方库几乎可以零配置。
二、微服务
1、什么是微服务?
微服务是一种架构风格,例如MVC三层架构 MVVM 微服务架构
实际上将业务拆封为模块,例如service-》模块、controller-》接口。要求在开发一个应用的时候,这个应用必须构建成一系列小服务的组合,可以通过进行http的方法进行互通。
2、单体服务架构
单体服务架构(all in one)是指我们讲一个应用中的所有应用服务都封装到一个应用中。
无论是ERP、CRM或是其他什么系统,都要将数据库访问、web访问等功能放到war包内。
好处:
易于开发和测试,方便部署
需要扩展时,复制多份war包,放到多台服务器上,使用负载均衡
坏处:
修改一个很小的地方,需要停掉整个服务,重新打包,部署war包
对于一个大型应用,不可能把所有内容放在一个应用里面,如何维护分工都是问题!
3、微服务架构
打破all in one的方式,将每个功能元素独立出来,把独立出来的功能元素动态组合,需要的功能元素拿来组合,需要多一些时可以整合多个功能元素。所以微服务架构是对功能元素进行复制,而不是对整个应用进行复制。
好处:
节省调用资源
每个功能元素的服务都是一个可替换的、可独立升级的软件代码
三、第一个Springboot程序
1、官网创建项目
前提准备
jdk1.8
maven 3.6.1
springboot:最新版
开发工具:IDEA
初次创建使用官网下载的项目来进行
创建项目有两种方式:
在官网:https://spring.io/projects/spring-boot#overview 最下面的quick start来进行创建项目(jar包)
创建项目->Spring Initializr(1.8,default) -> jdk版本设置,工程包名 -> 选择Springweb,创建完成
点击explore直接下载项目到本地,IDEA导入打开即可!!!
将没有用的直接删除掉,仅仅留下下面几个部分(注意.iml初步导入是没有的,我这里是后来截图的)
查看项目结构
建议开发目录都在根目录下面,这里是/com/changlu/helloworld/下,可以添加入controller、service、model、pojp目录等
看一下resource目录中的结构:
static:保存所有的静态资源,什么js、css之类的都在这下面
templates:保存所有的模板页面,Springboot默认jar包使用的是嵌入式的Tomcat,默认不支持JSP页面,所以在模板这里,我们可以使用模板引擎,比如freemaker、thymeleaf之类的
application.properties,这个是SpringBoot的配置文件。前面我们知道SpringBoot有很多默认配置,我们就可以在这个文件夹修改默认配置,比如端口之类的。
① HelloworldApplication.java
暂且知道该类是springboot的启动类即可
//程序主配置入口 @SpringBootApplication public class HelloworldApplication { public static void main(String[] args) { SpringApplication.run(HelloworldApplication.class, args); } }
启动即可看到如下内容:
访问一下看看:我们初始可以使用http://localhost:8080/以及http://localhost:8080/error来进行访问
② 看一下pom.xml中的web配置
首先看下spring-boot-starter-web:该依赖集成了tomcat、dispatcherservlet、spring-web(beans、core)、spring-webmvc(content、core、expression) <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
默认包含两个模块:
spring-boot-starter:启动器,核心模块,包括自动配置支持、日志和YAML,如果引入了spring-boot-starter-web,web模块可以去掉此配置,因为我们可以看到其中自动依赖了spring-boot-starter。实际配置文件中就是spring-boot-starter-web!
spring-boot-starter-test:测试模块,包括了JUnit、Hamcrest、Mokito
实际应用
①创建一个HelloController
在Controller目录中创建一个controller类来进行接收访问请求
//Controller 里面的方法都以 json 格式输出,不用再写什么 jackjson 配置的了 @RestController public class HelloworldController { @RequestMapping("/hello") public String hello(){ return "hello,springboot!"; } }
访问效果:
②打jar包来手动运行(√)
在IDEA中右侧的maven-helloworld-Lifecycle,选择package打包
接着我们使用powershell(管理员模式)在指定文件目录中来运行jar包,命令:java -jar .\helloworld-0.0.1-SNAPSHOT.jar
接下来可以通过访问http://localhost:8080/hello来进行测试!
2、手动创建项目
IDEA手动创建
为防止出现连接超时,我们设置对应的网址:http://start.springboot.io/
之后我们不选择web应用,之后自己手动添加依赖即可,创建完成!
若是出现连接超时,通过以下方法进行测试对应的网址
setting中设置一下:http://start.springboot.io/
添加web依赖
因为我们手动创建时没有勾选web,所以我们需要手动引入下面的依赖,否则创建web项目
spring-boot-starter是启动器,我们使用下面的依赖就可以把其删除了
<!--spring-boot-starter-web 自动对spring-boot-starter进行依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
创建Controller与设置端口(√)
设置端口:在/src/resource/application.properties
server.port=8081
创建Controller
@RestController @RequestMapping("/hello") public class HelloController { @GetMapping("/hello") public String hello(){ return "hello,springboot"; } }
@RestController:是@Controller与@Responsebody结合
@GetMapping():获取get方式的请求
访问:
自定义banner图标(√)
banner图标指的是springboot初始运行时出现的图标
初始图:
自定义方法:
在/src/resource/下创建一个banner.txt,将自定义图标的字符串放进去即可,那么自定义图标如何获取呢?
自定义banner网站:https://www.bootschool.net/ascii
// _ooOoo_ // // o8888888o // // 88" . "88 // // (| ^_^ |) // // O\ = /O // // ____/`---'\____ // // .' \\| |// `. // // / \\||| : |||// \ // // / _||||| -:- |||||- \ // // | | \\\ - /// | | // // | \_| ''\---/'' | | // // \ .-\__ `-` ___/-. / // // ___`. .' /--.--\ `. . ___ // // ."" '< `.___\_<|>_/___.' >'"". // // | | : `- \`.;`\ _ /`;.`/ - ` : | | // // \ \ `-. \_ __\ /__ _/ .-` / / // // ========`-.____`-.___\_____/___.-`____.-'======== // // `=---=' // // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // // 佛祖保佑 永不宕机 永无BUG //
注意banner.txt创建之后,该文件前面有个类似于启动的图标说明springboot检测到了该配置文件,我们运行即可看到效果了!!!
热部署(√)
对于创建使用springboot项目,我们有时候会出现错误而修改程序代码就会有一个不断重启项目的情况,针对这种情况我们使用热部署来解决,简单来说就是你修改代码可以实时生效
①主要配置:在pom.xml中配置:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <!--用于明确表示编译版本配置有效--> <fork>true</fork> </configuration> </plugin> </plugins> </build>
②在settings中勾选自动编译工程,让idea能够自动编译
③在工程中按下Shift+Ctrl+Alt+/,选择Registry,进行勾选
注意:如果你的springboot的热部署没有生效,看一下②③两步在你的idea中有没有配置。
还有一个方法,就是手动使用build编译在运行时,也是可以的,如下
四、原理初探
pom.xml配置
pom.xml
parent标签中spring-boot-starter-parent:包含依赖spring-boot-dependencies其中包含了对应版本的核心依赖,包含资源配置文件
spring-boot-starter:启动器,其实配置spring-boot-starter-web可以代替它,自动依赖了启动器
启动器
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency>
启动器就是Springboot的启动场景
例如我们使用spring-boot-stater-web,就会帮我们自动导入web环境所有的依赖,例如Spring、springmvc、tomcat
springboot会将所有的功能场景,都变成一个个启动器,我们需要什么功能,只需要引入对应的启动器即可stater
查看springboot的文档:springboot-stater获取
主程序
主程序如下
//标注这个类是一个springboot的应用 启动类下的资源所有都被导入 @SpringBootApplication public class HelloApplication { public static void main(String[] args) { //将springboot进行启用 SpringApplication.run(HelloApplication.class, args); } }
@SpringBootApplication深入
注解:@SpringBootApplication下
@SpringBootConfiguration:springboot的配置(1.1) @Configuration:spring的配置类(1.1.1) @Component:说明其是spring的组件(1.1.1.1) @EnableAutoConfiguration:项目启动时向IOC容器中快速注入Bean,开启自动配置功能(1.2) @AutoConfigurationPackage:自动配置包(1.2.1) @Import(AutoConfigurationPackages.Registrar.class):自动注册包 配置(1.2.1.1) @Import(AutoConfigurationImportSelector.class):快速导入bean到IOC容器中(1.2.2) @ComponentScan:扫描当前主启动类同级的包
上面部分类中详解
AutoConfigurationImportSelector(1.2.2中自动配置导入选择类中列举介绍):
//获取所有的配置 List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { //加载对应启动类下的资源 List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),getBeanClassLoader()); //断言,非空 Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you " + "are using a custom packaging, make sure that file is correct."); return configurations; }
这里断言非空方法中出现:META-INF/spring.factories是jar包下的一个核心配置文件
实际上我们也可通过上面加载对应启动类下的资源方法SpringFactoriesLoader.loadFactoryNames中的loadSpringFactories方法里的classLoader.getResources(FACTORIES_RESOURCE_LOCATION);这个参数得到META-INF/spring.factories,路径如下:
打开spring.factories部分内容如下:
简而言之:就是通过上面1.2.2这个注解在启动的时候扫描并加载帮我们将META-INF/spring.factories下的自动配置类进行了遍历扫描,但是不一定生效,要判断条件是否成立,只要导入了对应的start,就有对应的启动器,有了启动器,我们自动装配就会生效,然后配置成功!
总结说明:
springboot在启动时,从类路径下的/META-INF/spring.factories获取指定的值。通过将这些自动配置的类导入容器,自动配置就会生效,帮我们进行自动配置!以前需要我们配置的东西,springboot都帮你做了!
整合JavaEE,解决方案和自动配置的东西都在spring-boot-autoconfigure-2.2.0.RELEASE.jar这个包下。
从容器中(spring.factories)中能够看到存在需要XXXAutoConfiguration的文件(包含@Bean),就是这些类给容器导入了这个场景所需要的所有组件,并自动配置,包含@Configuaration。都是以JavaConfig的方式来进行配置!
有了自动配置类,直接免去了我们手动编写配置文件的工作!
原理分析思维导图见:01、自动配置原理分析
SpringApplication.run介绍
本以为只是运行了一个main方法,却是运行了一个服务
public static void main(String[] args) { //将springboot进行启用 SpringApplication.run(HelloApplication.class, args); }
该方法主要做的事情是SpringApplication进行实例化以及run方法的执行。
该类主要做了以下四件事情:
推断应用的类型是普通过的项目还是web项目
查找并加载所有可用初始化器,设置到initializers属性中
找出所有的应用程序监听器,设置到listeners属性中
推断并设置main方法的定义类,找到运行的主类
关于springboot,谈谈理解:主要在自动装配与run()里谈,约定大于配置!
流程图如下
测试类 @SpringBootTest:单元测试类 //指定这个类是单元测试类:在这个类中能够自动获取IOC容器中的Bean @SpringBootTest class HelloApplicationTests { @Autowired private HelloController helloController; @Test void contextLoads() { } }
实际开发中不会用到,随着项目越来越大,一般不会使用一个测试方法来检验代码!