学习资料

官方文档

SpringBoot官方文档-GA
image.png

教学视频

尚硅谷雷神SpringBoot2零基础入门springboot·全套完整版[87]

内容 日期 进度

- @Configuration标签
6/12 8

- 底层的注解
6/14 9、10、11、12、13

- 自动配置的原理
6/15 14、15

- 开发小技巧
- yaml配置文件
6/16 16、17、18、19、20

- 静态文件
6/18 21、22、23

- 静态资源配置原理
- 404
- index
6/19 24

- 静态资源访问的原理
- 修改表单实现rest风格
6/21 25、26、27

- 参数的注解
6/22 28、29、30

- 请求的获取参数的原理
6/23 31

- model map 的原理
6/25 32、33
7/1 34

黑马程序员SpringBoot2全套视频教程

  1. []:rest风格:访问网络资源的格式。
    1. 优点:简化语句、隐藏行为

image.png
笔记为了复现教学
Spring Boot - 图3

基础入门

一、Spring与SpringBoot

什么是SpringBoot?

  • 开发包,使得开发变得更简单。

常用注解?

  • SpringBootApplication:这是一个Spring Boot应用,
  • Controller:这是一个控制器
  • ResponseBody:这个控制器返回字符串。
  • RestController:(Controller+ResponseBody)这是一个控制器,直接返回字符串到页面,而不是返回页面。

    二、SpringBoot2入门

    2、HelloWord

    ```xml org.springframework.boot spring-boot-starter-parent 2.7.0

org.springframework.boot spring-boot-starter-web

  1. ```java
  2. /**
  3. * @SpringBootApplication:这是spring boot 应用
  4. */
  5. @SpringBootApplication
  6. public class MainApplication {
  7. public static void main(String[] args) {
  8. SpringApplication.run(MainApplication.class,args);
  9. }
  10. }
  1. package com.wuzhi.boot.controller;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.web.bind.annotation.RequestMapping;
  4. import org.springframework.web.bind.annotation.ResponseBody;
  5. @ResponseBody
  6. @Controller
  7. public class HelloController {
  8. @RequestMapping("/hello")
  9. public String Hello(){
  10. return "<h1>hello word</h1>";
  11. }
  12. }
  1. #application.properties
  2. server.port=8082
  1. <build>
  2. <plugins>
  3. <plugin>
  4. <groupId>org.springframework.boot</groupId>
  5. <artifactId>spring-boot-maven-plugin</artifactId>
  6. </plugin>
  7. </plugins>
  8. </build>
  1. java -jar boot-01-hello-1.0-SNAPSHOT.jar

三、了解自动装配

1、SpringBoot特点

1.1、依赖管理

1.2、自动装配

点击spring-boot-starter-web即可查看

  • 配置好tomcat
  • 配置好SpringMVC

    1. #ctrl+spring-boot-starter-web
    2. <dependencies>
    3. <dependency>
    4. <groupId>org.springframework.boot</groupId>
    5. <artifactId>spring-boot-starter-web</artifactId>
    6. </dependency>
    7. </dependencies>
  • 配置好乱码问题

  • 配置好视图解析器

    1. @SpringBootApplication
    2. public class MainApplication {
    3. public static void main(String[] args) {
    4. //1.返回IOC容器
    5. ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
    6. //2.查看容器的组件
    7. String[] names = run.getBeanDefinitionNames();
    8. for (String name :
    9. names) {
    10. System.out.println(name);
    11. }
    12. }
    13. }
  • 默认包结构:其他包放在主程序同级或者子包都能扫描。

  • 配置拥有默认值点开依赖:spring-boot-autoconfigure
  • 按需加载包:starter
    1. <dependency>
    2. <groupId>org.springframework.boot</groupId>
    3. <artifactId>spring-boot-autoconfigure</artifactId>
    4. <version>2.7.0</version>
    5. <scope>compile</scope>
    6. </dependency>

    2、容器功能

    2.1、组件添加

  1. @Configuration
  2. @Bean、@Component、Controller、Service、Reposity
  3. ComponentScan、Import、ImportResouce(“”)
  4. Conditional
    • 满足某种条件将依赖进行注入。
  • @ConditionalOnBean(name = “tom”):容器中有tom才将这个组件才注入

    2.2、原生配置文件引入

  • @ImportResource(“classpath:bean.xml”)

    2.3、属性值绑定

    将.properties中的文件的属性值封装到bean中。

  1. @Component+@ConfigurationProperties(prefix = “”)

    1. mycar.brand=tesla
    2. mycar.price=12000
    1. @Component
    2. @ConfigurationProperties(prefix = "mycar")//放到容器中这个注解才生效
    3. public class Car {
    4. private String brand;
    5. private Integer price;
    6. public String getBrand() {
    7. return brand;
    8. }
    9. public void setBrand(String brand) {
    10. this.brand = brand;
    11. }
    12. public Integer getPrice() {
    13. return price;
    14. }
    15. public void setPrice(Integer price) {
    16. this.price = price;
    17. }
    18. }
  2. @EnableConfigurationProperties(Car.class)+@ConfigurationProperties(prefix = “mycar”)

    1. @Configuration
    2. @EnableConfigurationProperties(Car.class)//放入第三方bean到容器
    3. public class MyConfig {

    3、自动配置原理入门

    3.1、引导加载配置类

    1. @SpringBootConfiguration //->:@Configuration:这是一个配置类 MainApplication也是配置类
    2. @EnableAutoConfiguration
    3. //->:@AutoConfigurationPackage ->
    4. //->:@Import({AutoConfigurationImportSelector.class})
    5. @ComponentScan(
    6. excludeFilters = {@Filter(
    7. type = FilterType.CUSTOM,
    8. classes = {TypeExcludeFilter.class}
    9. ), @Filter(
    10. type = FilterType.CUSTOM,
    11. classes = {AutoConfigurationExcludeFilter.class}
    12. )}
    13. )//指定扫描什么包
    1. @Import({Registrar.class})
    2. public @interface AutoConfigurationPackage {

    ```java List configurations = this.getCandidateConfigurations(annotationMetadata, attributes);

  1. ```java
  2. //->META-INF->spring.factories

3.2、按需配置

  • 一股脑全部加载,但是根据注解ConditionalOnXXX使得,如果不导入包组件就不会生效。

    3.3、默认修改配置

  • 底层默认配置了属性,如果用户配置了,用户的配置优先

    1. @ConditionalOnProperty(
    2. prefix = "server.servlet.encoding",
    3. value = {"enabled"},
    4. matchIfMissing = true
    5. )
    1. @Bean
    2. @ConditionalOnMissingBean
    3. public CharacterEncodingFilter characterEncodingFilter() {
    4. CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
    5. filter.setEncoding(this.properties.getCharset().name());
    6. filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.web.servlet.server.Encoding.Type.REQUEST));
    7. filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.web.servlet.server.Encoding.Type.RESPONSE));
    8. return filter;
    9. }

    3.4、总结

  1. spring boot先加载所有的配置类。
  2. 配置类按照导入的依赖类条件进行生效,并且配置类有默认值,从XXXProperties里面去取,XXXProperties绑定了配置文件application.properties。
  3. 生效的配置类就会给容器装配。
  4. 只要容器中有就有这些功能。
  5. 并且用户可以修改配置类。

    4、开发小技巧

    4.1、一般步骤

  6. 引入场景

  7. 查看自动配置了那些属性。application.properties中添加配置debug=true
  8. 是否需要修改配置项。

    1. 自定义配置
    2. 自定义组件

      4.2、Lombok

      1. @NoArgsConstructor//无参构造器
      2. @AllArgsConstructor//为所有参数生成构造器
      3. @ToString//生成ToString
      4. @Data//编译时生成getter setter
      5. @ConfigurationProperties(prefix = "mycar")
      6. public class Car {
      7. private String brand;
      8. private Integer price;
      9. }
      1. @Slf4j//log.infor("写入日志文件")
      2. @RestController
      3. public class HelloController {
      4. @Autowired
      5. Car car;
      6. @RequestMapping("/car")
      7. public Car car(){
      8. log.info("car请求");
      9. return car;
      10. }
      11. }

      4.3、dev-tools

      1. <dependency>
      2. <groupId>org.springframework.boot</groupId>
      3. <artifactId>spring-boot-devtools</artifactId>
      4. </dependency>

      4.4、Spring Initailar

      image.png

      核心功能

      Spring Boot - 图5

      四、配置文件

      1、properties

      properties>yml>yaml:这三个文件都会加载

      2、yaml

      五、Web开发

      1、自动配置概览

      image.png

      2、简单功能分析

      2.1、静态资源目录

      存储地址:/static (or /publicor /resources or /META-INF/resources)
      访问方式:/+资源名称
      过程:先用Contrller处理,不能处理后用/**处理。
      指定访问静态资源的前缀:spring.mvc.static-path-pattern=

      2.2、欢迎页面

  9. index.html放到静态资源目录下。

    2.3、图标

  10. 将图标favicon.ico放到静态资源下。

  11. 记得强制刷新。

    2.4、错误路径

  12. /error/404.html,放到/static

    2.5、静态资源配置原理

  13. 主要的配置类WebMvcAutoConfiguration

  14. 内部类,看它绑定了那些属性。
  15. 一个内部类WebMvcAutoConfigurationAdapter
  16. 这个内部类的方法addResourceHandlers,调取静态资源位置。

    1. public void addResourceHandlers(ResourceHandlerRegistry registry) {
    2. if (!this.resourceProperties.isAddMappings()) {
    3. logger.debug("Default resource handling disabled");
    4. } else {
    5. this.addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
    6. this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
    7. registration.addResourceLocations(this.resourceProperties.getStaticLocations());
    8. if (this.servletContext != null) {
    9. ServletContextResource resource = new ServletContextResource(this.servletContext, "/");
    10. registration.addResourceLocations(new Resource[]{resource});
    11. }
    12. });
    13. }
    14. }
  17. 禁用所有静态资源

    1. spring:
    2. web:
    3. resources:
    4. add-mappings: false #所有的静态资源都访问不了
  18. 欢迎页处理

    1. @Bean
    2. public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
    3. WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());
    4. welcomePageHandlerMapping.setInterceptors(this.getInterceptors(mvcConversionService, mvcResourceUrlProvider));
    5. welcomePageHandlerMapping.setCorsConfigurations(this.getCorsConfigurations());
    6. return welcomePageHandlerMapping;
    7. }

    3、请求参数处理

    0、请求映射

  19. rest风格支持:(利用HTTP请求动词表示对资源的访问)

    1. GET-查 PUT-修改 POST-保存 DELETE-删除
  20. 表单提交参数的rest风格处理办法:拦截POST请求,根据_method的值重写请求。 ```html

    //name代表参数
  1. ```java
  2. @Bean
  3. @ConditionalOnMissingBean({HiddenHttpMethodFilter.class})
  4. @ConditionalOnProperty(
  5. prefix = "spring.mvc.hiddenmethod.filter",
  6. name = {"enabled"}
  7. )
  8. public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
  9. return new OrderedHiddenHttpMethodFilter();
  10. }
  1. protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
  2. HttpServletRequest requestToUse = request;
  3. if ("POST".equals(request.getMethod()) && request.getAttribute("javax.servlet.error.exception") == null) {
  4. //methodParam = _method 得到参数为 _method的参数的值
  5. String paramValue = request.getParameter(this.methodParam);
  6. if (StringUtils.hasLength(paramValue)) {
  7. String method = paramValue.toUpperCase(Locale.ENGLISH);
  8. if (ALLOWED_METHODS.contains(method)) {
  9. requestToUse = new HiddenHttpMethodFilter.HttpMethodRequestWrapper(request, method);
  10. }
  11. }
  12. }
  13. filterChain.doFilter((ServletRequest)requestToUse, response);
  14. }
  1. spring.mvc.hiddenmethod.filter.enabled=true
  1. 请求方法等价写法 ```java //两个相等 // @RequestMapping(value = “/user”, method = RequestMethod.GET) @GetMapping(“/user”) public String getUser() { return “user-get”; }

//两个是相等的 // @RequestMapping(value = “/user”, method = RequestMethod.DELETE) @DeleteMapping(“/user”) public String deleteUser() { return “user-delete”; }

// @RequestMapping(value = “/user”, method = RequestMethod.POST) @PostMapping(“/user”) public String PostUser() { return “user-post”; }

@PutMapping(“/user”) public String PutUser() { return “user-put”; }

  1. 4. 请求映射原理:`DispatcherServlet`类->`doDispatch`方法
  2. 1. 所有的请求都在`HandlerMapping`
  3. <a name="Cw56K"></a>
  4. #### 1、普通参数与基本注解
  5. 1. **注解**
  6. - @PathVariable:从请求路径上取值
  7. - @RequestHeader:获取请求头中的参数
  8. - @RequestParam:从请求的参数上获取
  9. - @CookieValue:获取cookie的值,cookie是用户的信息。
  10. ```java
  11. // car/2/owner/gonglize?age=18&height=173
  12. @GetMapping("/car/{id}/owner/{username}")
  13. public Map<String, Object> getCar(@PathVariable("id") Integer id,
  14. @PathVariable("username") String name,
  15. @RequestHeader("User-Agent") String agent,
  16. @RequestHeader Map<String, String> header,
  17. @RequestParam("age") Integer age,
  18. @RequestParam("height") Integer height,
  19. @CookieValue("Idea-46648a83") Cookie cookie) {
  20. Map<String, Object> map = new HashMap<>();
  21. map.put("id", id);
  22. map.put("username", name);
  23. map.put("agent", agent);
  24. // map.put("header", header);
  25. map.put("age", age);
  26. map.put("height", height);
  27. map.put("cookie", cookie);
  28. System.out.println(cookie.getName() + "================" + cookie.getValue());
  29. return map;
  30. }
  • @RequestBody:获取post表单中的数据

    1. <form action="/save" method="post">
    2. <input name="userName">
    3. <input name="email">
    4. <input type="submit" value="提交">
    5. </form>
    1. /**
    2. * post请求表单
    3. *
    4. * @return
    5. */
    6. @PostMapping("/save")
    7. public Map<String, Object> postMethod(@RequestBody String content) {
    8. Map<String, Object> map = new HashMap<>();
    9. map.put("content", content);
    10. return map;
    11. }
  • @RequestAttribute:用于得到转发后requst中的属性值。 ```java @GetMapping(“/goto”) public String goToPage(HttpServletRequest request) {

    request.setAttribute(“msg”, “成功了”); request.setAttribute(“msg1”, “我成功了”);

    return “forward:/success”; }

@ResponseBody @GetMapping(“/success”) public String success(@RequestAttribute(“msg”) String msg) { return msg; }

  1. - @MatrixVariable:处理矩阵变量的请求方式。`UrlPathHelper`->removeSemicolonContent用来支持矩阵变量。
  2. ```java
  3. /**
  4. * 配置矩阵变量请求:第二种写法
  5. */
  6. @Bean
  7. public WebMvcConfigurer webMvcConfigurer(){
  8. return new WebMvcConfigurer() {
  9. @Override
  10. public void configurePathMatch(PathMatchConfigurer configurer) {
  11. UrlPathHelper urlPathHelper = new UrlPathHelper();
  12. //不移除 矩阵变量的请求生效
  13. urlPathHelper.setRemoveSemicolonContent(false);
  14. WebMvcConfigurer.super.configurePathMatch(configurer);
  15. }
  16. };
  17. }
  1. // boss/1;age=45/2;age=22
  2. @GetMapping("boss/{bossId}/{empId}")
  3. public Map boss(@MatrixVariable(value = "age", pathVar = "bossId") Integer bossAge,
  4. @MatrixVariable(value = "age", pathVar = "empId") Integer empAge) {
  5. Map<String, Object> map = new HashMap<>();
  6. map.put("bossAge",bossAge);
  7. map.put("empAge",empAge);
  8. return map;
  9. }
  1. Servlet API
  • 处理原生的请求:在类ServletRequestMethodArgumentResolver->的方法resolveArgument中可以找到所有可以处理的请求。
    1. //HttpSession
    2. //InputStream
    3. //Reader
    4. //Principal
  1. 复杂参数
  • Map、Model=request.setAttribute,他们是一个东西,最后将数据放到请求域中。

    1. @GetMapping("/params")
    2. public String testParam(Map<String,Object> map,
    3. Model model,
    4. HttpServletRequest request,
    5. HttpServletResponse response){
    6. map.put("map","mapValue");
    7. model.addAttribute("model","modelValue");
    8. request.setAttribute("request","requestValue");
    9. Cookie cookie = new Cookie("cookie","cookieValue");
    10. response.addCookie(cookie);
    11. return "forward:goto";
    12. }
  • RedirectAttributes、ServletResponse

  1. 自定义对象参数

    2、POJO封装过程

    3、参数处理的原理

  2. handlerMapping中找到能够处理的handler(Controller.method)

  3. 为handler找到handlerAdapters

image.png

  1. 执行目标方法

    1. mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
  2. 参数解析器:确定方法参数的值是什么。一种参数解析器,可以得到一种请求方式的参数。

  3. 返回值解析器
  4. 执行Controller
    1. Object returnValue = this.invokeForRequest(webRequest, mavContainer, providedArgs);

    4、响应数据与内容协商