Java Spring

概述

  • Java 世界应用的事实标准
  • Spring 容器 => 一个 IoC(Inverse of Control) 容器 => 自动化管理对象相关依赖的容器 => 模块之间的依赖越来越复杂,需要 Spring 容器帮助我们处理模块之间的依赖关系
  • Spring MVC => 基于 Spring 和 Servlet 的 Web 应用框架 => 支持 Servlet 和网络请求的 Spring 程序
  • Servlet => -let 小... => 小服务器 => 把外界的 http 请求封装成一个对象交给上层的 WebApp(网络应用) => WebApp 网络应用的事实标准就是 Spring MVC | Spring Boot => Tomcat | Jetty 框架
    • booklet => 小册子
    • applet => 小程序
    • doclet =>
  • Spring Boot => 集成度和自动化程度更高 => 内嵌了 Servlet => Servlet + Spring MVC

上古时代

Spring 之前 => 一个 Main 程序

  • 非常轻量,适用于非常简单的场景 => 易懂
  • 一旦规模上来之后 => 难易维护

拆分并手动管理

  • 方便测试 + 方便共同开发 + 方便维护
  • 依赖关系纷繁复杂

Spring 容器核心概念

  • Bean => 容器中的最小工作单元,通常为一个 Java 对象
  • BeanFactory | ApplicationContext => 容器本身对应的 Java 对象
  • DI => Dependency Injection => 依赖注入 => 容器负责注入所有依赖
  • IoC => Inverse of Control => 控制反转 => 用户将控制权交给容器 => 不需要控制所有依赖的装配和运行,只需要声明之间的依赖,Spring 容器自动进行装配和运行 => 在 start 的时候就把所有依赖已经装配和运行,不是在运行代码时进行装配

手写一个简单的 IoC 实现

  1. 定义 Bean => resources/beans.properties
  2. 加载 Bean 的定义 => java.util.Properties.load
  3. 实例化 Bean => reflect => Map
  4. 查找依赖,实现自动注入 => @Autowired => Field.set(, )

    Spring IoC 实现

    • 在 XML 里面定义 Bean
    • org.springframework.beans.factory.config.BeanDefinition.java 的载入和解析
    • Bean 的实例化和依赖注入

    Web 应用

    处理 HTTP 请求

    1. 从 HTTP 请求路径中提取参数 => @PathVariable
    2. 从 HTTP 请求中提取 query string => @RequestParam
    3. 从 HTTP 请求中接收 body(payload | entity) 中的参数
      • Content-Type=application/json => @RequestBody => 提取整个 body 中的对象
      • Content-Type=x-www-form-urlencoded => @Param => 提取 body 中的参数
        /**
          * curl --location --request POST '127.0.0.1:8080/test' --header 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'username=123456' --data-urlencode 'password=success'
          */
        public class Controller {
            @PostMapping(value = "/test", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
            @ResponseBody
            public Response test(@Param("username") String username, @Param("password") String password) {
                System.out.println("username = " + username);
                System.out.println("password = " + password);
                return Response.success(new User());
            }
        }
        

    返回 HTTP 响应

    1. status code
    2. HTTP response header => Client request Header Accept <=> Server Response Content-Type => 服务端根据客户端的 Accept 动态返回 Response Content-Type
    3. HTTP response body
      • HTML
      • HttpServletResponse
      • JSON => 返回对象,并自动格式化成 JSON => @ResponseBody
      • 模板引擎渲染 => JSP | Velocity | Freemaker

    Spring Boot Annotation for Controller

    Spring MVC 提供参数自动绑定 => 自动的从发起的 HTTP 请求中解析参数并且绑定到对应的方法上

    1. @RestController => A convenience annotation that is itself annotated with @Controller and @ResponseBody.
    2. @Controller => Indicates that an annotated class is a "Controller" (e.g. a web controller)
    3. @ResponseBody => Annotation that indicates a method return value should be bound to the web response body. Supported for annotated handler methods.
    4. @RequestMapping => Annotation for mapping web requests onto methods in request-handling classes with flexiblemethod signatures.
    5. @GetMapping => Annotation for mapping HTTP GET requests onto specific handler methods.
    6. @PostMapping => Annotation for mapping HTTP POST requests onto specific handler methods.
    7. @PutMapping => Annotation for mapping HTTP PUT requests onto specific handler methods.
    8. @DeleteMapping => Annotation for mapping HTTP DELETE requests onto specific handler methods.
    9. @PatchMapping => Annotation for mapping HTTP PATCH requests onto specific handler methods.

    三层架构

    应用逻辑更加清晰 + 代码复用

    1. Controller => 做和 HTTP 请求相关 => 接收和解析参数,调用 Service 方法,获得响应之后封装成结果返回
    2. Service => 业务代码
    3. Dao => 做数据库增删改查

    项目文件

    main/java/example

    • /annotation package => 注解包
    • /common package => 工具相关
    • /configuration package => 配置包 => MyConfiguration.java => @Configuration => 可以声明 Bean
    • /controller package => controller 包
    • /dao package => 数据库相关
    • /entity package => 实体类
    • /service package => 服务包

    模板引擎

    • 模板引擎 => 后端渲染 HTML => 后端直接返回带有数据的 HTML
    • Freemaker => FreeMaker 对 Spring 继承约定 => resources/templates 目录下存储模板引擎文件 => index.ftlh
    • Spring Boot ModuleAndView == index.ftlh + 数据 => ModuleAndView == 模板引擎 + 数据 => ModuleAndView class => new ModuleAndView(<模板引擎 file>, model); => Spring Boot Controller 返回字符串时默认处理方式

    Servlet

    • Servlet 容器是遵循 Servlet 规范,为 Servlet 提供宿主环境的一个 Java 应用
    • Servlet 就是一个小服务器。其封装了一系列的HTTP操作,只需调用其提供的方法,即可组装成相应的报文,无需手动拼装。通过高层次的抽象来简化Web应用的开发,其是现代 Java Web 应用开发的基石,大部分的 Web 应用基本上都是建立在 Servlet 之上的
    • Servlet 只是一个 Interface,Java Web 应用只需要调用接口的方法,接口的具体实现由 Servlet 容器决定。所有的基于 Servlet 的应用都需要运行在 Servlet 容器中。
    • 应用不需要关心 Servlet 的具体实现,只需调用 Servlet 接口的方法即可(体现了 Java 的多态)。 优点:应用完全独立于 Servlet 容器进行开发

    RESTful API

    一种设计 API 的约定 => 优雅

    1. 使用 HTTP 动词代表动作
      • GET => 获取资源
      • POST => 新建资源
      • PUT => 更新资源
      • DELETE => 删除资源
    2. 使用 URL(名词)来代表资源
      • 资源里面没有动词
      • 使用负数来代表资源列表
    RESTful API design

    知识点

    1. Building an Application with Spring Boot
    2. wire => 电线 n. 装配 v. => Autowired => 在 Spring 中使用 @Autowired 进行依赖的装配和运行 => @Autowired 不推荐写在属性上,更加推荐构造器注入,即 @Autowired 写在构造器上,Spring 容器可以识别,并且还可以 mock,进行单元测试。更推荐使用 @Inject@Autowired 写在 Field 上,一旦当前类脱离 Spring 容器,他就不能正常工作,这个是通过反射注入,在写单元测试的时候,也需要使用反射注
      // 不推荐 => 写 Test 的时候需要使用反射将 sqlSession 注入进去
      @Autowired
      private SqlSession sqlSession; 
      
      // 推荐使用构造器注入 => 写 Test 的时候更好注入相关依赖
      private SqlSession sqlSession;
      
      @Autowired
      public TestConstructor(SqlSession sqlSession) {
          this.sqlSession = sqlSession;
      }
      
    3. 使用注解声明依赖,依赖如何被注入进去,是 Spring 容器来决定的
    4. .properties => Java 原生支持的配置文件 => java.util.Properties
      # 注释 a: key 1: value
      a=1
      
    5. 循环依赖的本质是在创造期的依赖,创造 A 的时候需要提供 B,但是创造 B 的时候需要提供 A。创造出来之后再分别对他们进行设值,这样的循环依赖容易解决
    6. 幂等 => 一个 HTTP 方法是幂等的 => 同样的请求被执行一次与连续执行多次的效果是一样的,服务器的状态也是一样的 => 幂等方法不应该具有副作用 => 幂等性只与后端服务器的实际状态有关,而每一次请求接收到的状态码不一定相同
      • GET | HEAD | PUT | DELETE => 幂等
      • POST => 不幂等
    7. Safe => 一个 HTTP 方法是安全的 => 这个方法不会修改服务器的数据 => 对服务器只读操作的方法 => 所有 Safe 的方法都是幂等的 => 幂等但是不安全的方法:DELETE
      • GET | HEAD | OPTIONS => Safe
      • PUT | DELETE | POST => no Safe
    8. HTTP request => Port => Servlet 容器 => WebApp => Servlet 容器 => Port => HTTP response
      Servlet 容器 => 字节流与 Java 对象相互转换的中间层 => HttpServletRequest + HttpServletResponse
    9. spring-boot-starter-xxx => SpringBoot 模块
    10. 在 Spring 中所有的需要当做 Bean 去管理的可以加 @Service | @Component => 使用注解告知 Spring 这个类是一个 Bean,是一个 Service,是一个未来要把这个类变成对象,这个对象可以被依赖,可以依赖别人,可以进行依赖注入,可以去完成非常复杂的操作
    11. Spring 约定,放在 static 目录下文件可以在浏览器中直接访问 => resources/static/index.html => http://localhost:8080/index.html
    12. 前后端分离 vs 后端渲染
      • 前端渲染 => 前端通过 JavaScript 进行数据的获取,动态的渲染到页面中 =>

    你可能感兴趣的:(Java Spring)