递归(效率低)
不断调用自己
斐波那契数列
第三个数开始是前两个数之和
汉诺塔(递归)
所有问题都考虑成一个盘子和两个盘子的情况!!!!!!
1 | public class TestHanoi { |
以三个盘子为例:
不断调用自己
第三个数开始是前两个数之和
所有问题都考虑成一个盘子和两个盘子的情况!!!!!!
1 | public class TestHanoi { |
以三个盘子为例:
1 | 本质上就是一个Maven坐标,整合了完成一个功能需要的所有坐标 |
1 | 遵循约定大约配置的原则,在boot程序启动后,一些bean对象会自动注入到ioc容器,不需要手动声明,简化开发 |
1 | 1.内嵌的Tomcat、Jetty(无需部署WAR文件,只需要jar包即可) |
基于Spring官方骨架,创建SpringBoot工程
基本信息描述完毕之后,勾选web开发相关依赖
点击Finish之后,就会联网创建这个SpringBoot工程,创建好之后,结构如下:
运行SpringBoot自动生成的引导类
运行SpringBoot自动生成的引导类
打开浏览器,输入 http://localhost:8080/hello
书写:
获取:
1 | @Value("${键名}") |
整体图
1 | package com.itheima.springbootmybatis.pojo; |
1 | package com.itheima.springbootmybatis.mapper; |
1 | package com.itheima.springbootmybatis.Service; |
1 | package com.itheima.springbootmybatis.Service.impl; |
1 | package com.itheima.springbootmybatis.controller; |
如果要注册的bean对象来自于第三方(不是自定义的),是无法用 @Component 及衍生注解声明bean的只能使用以下两种方式去解决bean注解
2.存放到配置类(@Configuration)
配置类是可以写很多bean对象,并且配置类必须存放在启动类的同级和下一级包位置,方便Bean扫描(如果放在外面就需要方法2import注解了)
2.导入ImportSelector接口实现类
先创建一个java类重写ImportSelector接口的方法,返回值就是一个数组(要放入的bean对象)
然后在启动类中添加import注解就可以
然后在启动类中添加import注解就可以
Springboot提供了Conditional注解解决注册时候对象赋值问题,但是过于复杂所以给出了常用的三个相关注解
从配置文件中的读取,读取成功注入,读取失败不注入
因为Country需要从配置文件中读取注入,失败了所以没有注入,这样的话下面的province就会注入
如果环境中有当前类就注入,没有就不注入
上图描述:
现在的情况: 导入jar包的时候里面不仅仅有类,还有配置类,imports配置文件等,不需要添加任何其他操作
之前开发的SpringBoot入门案例中,我们通过maven引入的依赖,是没有指定具体的依赖版本号的。因为每一个SpringBoot工程,都有一个父工程。依赖的版本号,在父工程中统一管理
我们的SpringBoot中,引入了web运行环境(也就是引入spring-boot-starter-web起步依赖),其内部已经集成了内置的Tomcat服务器。
我们可以通过IDEA开发工具右侧的maven面板中,就可以看到当前工程引入的依赖。其中已经将Tomcat的相关依赖传递下来了,也就是说在SpringBoot中可以直接使用Tomcat服务器
当我们运行SpringBoot的引导类时(运行main方法),就会看到命令行输出的日志,其中占用8080端口的就是Tomcat
web后端开发现在基本上都是基于标准的三层架构进行开发的,在三层架构当中,Controller控制器层负责接收请求响应数据,Service业务层负责具体的业务逻辑处理,而Dao数据访问层也叫持久层,就是用来处理数据访问操作的,来完成数据库当中数据的增删改查操作。
在三层架构当中,前端发起请求首先会到达Controller(不进行逻辑处理),然后Controller会直接调用Service 进行逻辑处理, Service再调用Dao完成数据访问操作
如果我们在执行具体的业务处理之前,需要去做一些通用的业务处理,比如:我们要进行统一的登录校验,我们要进行统一的字符编码等这些操作时,我们就可以借助于Javaweb当中三大组件之一的过滤器Filter或者是Spring当中提供的拦截器Interceptor来实现
而为了实现三层架构层与层之间的解耦,我们学习了Spring框架当中的第一大核心:IOC控制反转与DI依赖注入
所谓控制反转,指的是将对象创建的控制权由应用程序自身交给外部容器,这个容器就是我们常说的IOC容器或Spring容器。
而DI依赖注入指的是容器为程序提供运行时所需要的资源
除了IOC与DI我们还讲到了AOP面向切面编程,还有Spring中的事务管理、全局异常处理器,以及传递会话技术Cookie、Session以及新的会话跟踪解决方案JWT令牌,阿里云OSS对象存储服务,以及通过Mybatis持久层架构操作数据库等技术
我们在学习这些web后端开发技术的时候,我们都是基于主流的SpringBoot进行整合使用的。而SpringBoot又是用来简化开发,提高开发效率的。像过滤器、拦截器、IOC、DI、AOP、事务管理等这些技术到底是哪个框架提供的核心功能
Filter过滤器、Cookie、 Session这些都是传统的JavaWeb提供的技术。
JWT令牌、阿里云OSS对象存储服务,是现在企业项目中常见的一些解决方案。
IOC控制反转、DI依赖注入、AOP面向切面编程、事务管理、全局异常处理、拦截器等,这些技术都是 Spring Framework框架当中提供的核心功能。
Mybatis就是一个持久层的框架,是用来操作数据库的。
在Spring框架的生态中,对web程序开发提供了很好的支持,如:全局异常处理器、拦截器这些都是Spring框架中web开发模块所提供的功能,而Spring框架的web开发模块,我们也称为:SpringMVC
SpringMVC不是一个单独的框架,它是Spring框架的一部分,是Spring框架中的web开发模块,是用来简化原始的Servlet程序开发的
外界俗称的SSM,就是由:SpringMVC、Spring Framework、Mybatis三块组成。
基于传统的SSM框架进行整合开发项目会比较繁琐,而且效率也比较低,所以在现在的企业项目开发当中,基本上都是直接基于SpringBoot整合SSM进行项目开发的
单链表图示:
具体实现功能:
1. 添加节点(将指针不停指向下一个 判空)
2. 查询下一个节点(返回this.next)
3. 获取当前节点数据(返回this.data)
4. 判断是不是最后一个节点(只需要返回next是不是为空)
1 | public class Node { |
1 | public class Test { |
测试结果:
1 | //删除节点 |
方法实现解释:
1 | 假设现在是 1 --> 2 --> 3 --> 4 我们想把5插入到2后面 |
1 |
|
1 | public class Test { |
插入n5在n2后面:
循环链表图示:
对比单链表: 最后一个的next要指向开头的节点
1 | //下一个节点 |
具体代码:
1 | public class LoopNode { |
1 | public class Test { |
具体实现结果:
双向循环链表图示:
图示解释:
具体代码:
1 | public class DoubleNode { |
1 | public class Test { |
测试代码结果:
队列就跟排队一样
具体方法:
1. 入队(新数组在旧数组的基础上加元素然后替换旧数组)
2. 出队(需要取出第一个并且返回 其余的错位传给新数据 用新数组替换旧数组即可)
3. 判空(判断数组长度是否为空)
1 | public class MyQueue { |
1 | public class Test { |
具体结果:
1. 阿斯达请问
2. 阿斯达阿斯达
类
1 |
栈相当于手枪弹夹(不停地往下压子弹)
具体方法
1. 压入元素(新数组在旧数组基础上加上压入的元素之后替换旧数组)
2. 取出栈顶(取出并返回栈顶 然后新数组将其他元素放入后替换旧数组)
3. 查看栈顶(只需要返回数组最后一个)
4. 判空(返回数组长度是否为空)
1 | public class Main { |
1 | public class Test { |
最终执行测试:
SpringMVC图示:
文字描述:
前提:
web.xml文件中设置了DispatcherServlet的<url-pattern>为“/”
执行:
1. 用于发起请求 --> 请求一个控制器
2. 执行DispatcherServlet
3. DispatcherServlet调用 HandlerMapping的DefaultAnnotatiionHandlerMapping解析URL
4. 调用HandlerAdatper的AnnotationMethodHandlerAdapter
5. 调用Controller中的HandlerMethod
6. 当HandlerMehod执行完毕会返回view
7. view会被viewResovler进行视图解析 --> 调用jsp对应的.class文件 --> 运行
8. 将运行结果响应给客户端
发送请求时被拦截器拦截,在控制器(注解类的@RequestMapping)前后添加额外功能
1. AOP在特定方法前后进行扩充(对ServiceImpl实现类)
2. 拦截器对控制器方法(对Controller注解类)
1. SpringMVC拦截器 拦截控制器Controller
2. Filter过滤器 拦截任何请求
1 | public class DemoInterceptor implements HandlerInterceptor { |
拦截所有的控制器
1 | <mvc:interceptors> |
拦截特定的控制器
1 | <mvc:interceptors> |
1 | @Controller |
1 | <body> |
方法分析(3个):
1. preHandle : 控制器前(可以获得拦截的是哪个控制器)
2. @RequestMapping的注解方法 : 控制器 (写跳转哪个jsp页面)
3. postHandle : 控制器后 jsp前(日志记录/敏感词语过滤)
4. xxx.jsp jsp页面
5. afterCompletion : jsp之后(记录异常/异常写入日志)
最终执行结果:
多个拦截器同时生效 –> 拦截器栈
执行顺序和springmvc.xml里面配置的顺序有关
配置顺序 : 拦截器A --> 拦截器B
执行顺序(圆环!!!) :
preHandle(A) 最外层
preHandle(B) 次外层
控制器方法 中心(上面都是A在前 下面都是B在前)
postHandle(B)
postHandle(A)
JSP页面
afterCompletion(B)
afterCompletion(A)
1. 响应头没有设置:Content-Disposition(浏览器默认按照inline值处理)
1.1 inline 就是能显示就显示,不能显示就下载
2. 响应头设置:Content-Disposition="attachment;filename=文件名"
2.1 attachment 以附加形式下载
2.2 filename 就是下载时显示的下载文件名
1 | //添加files文件的静态资源配置 |
1 | <a href="download?fileName=a.txt">下载</a> |
1 | @Controller |
1. 基于apache的commons-fileupload.jar完成文件上传
2. MultipartResovler作用
2.1 客户端上传的文件 -->MutipartFile封装类
2.2 通过MutipartFile封装类获取到文件流
//enctype属性取值:
1. application/x-www-form-urlencoded(默认值) :普通表单数据(少量文字信息)
2. text/plain :大量文字信息(邮件/论文)
3. multipart/form-data : 表单中包含二进制文件内容
注解类传过去的类的对象和文件标签的name必须一致!!!
1 | <form action="upload" enctype="multipart/form-data" method="post"> //enctype属性取值是表单中包含二进制文件的值 |
编写MultipartResovler解析器和异常解析器
1 | <!-- MultipartResovler解析器 --> |
注解类MultipartFile类的对象和文件标签的name必须一致!!!
1 | @Controller |
1. page(当前页面)
2. request(一次请求中同一个对象)
3. session(一次会话)
3.1 只要客户端Cookie中传递的Jsessionid不变 --> session就不会重新实例化(不超过默认时间)
3.2 实际有效时间:
3.2.1 浏览器关闭 : cookie失效
3.2.2 默认时间 :tomcat的web.xml中配置
4 .application(关闭tomcat)
1. 使用原生Servlet(HandlerMethod参数中添加作用域对象)
2. 使用Map集合
3. 使用SpringMVC中Model接口
4. 使用SpringMVC中ModelAndView类
在HandlerMethod参数中 + 作用域对象
注解类:
1 | @Controller |
index.jsp页面(取出来):
1 | request:${requestScope.req }</br> |
map中的内容放入request作用域
spring会对map集合通过BindingAwareModelMap进行实例化
1 | @RequestMapping("demo02") |
内容最终放入到request作用域
1 | @RequestMapping("demo03") |
1 | @RequestMapping("demo04") |