Spring-boot学习笔记

参考:https://course.tianmaying.com/web-development
(1)Application类:

@SpringBootApplication
public class Application {
    public static void main(String[] args){
        SpringApplication.run(Application.class,args);
    }
}

(2)XML配置


<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0modelVersion>
    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>1.5.3.RELEASEversion>
    parent>

    <groupId>com.zwxgroupId>
    <artifactId>java-web-devartifactId>
    <version>1.0-SNAPSHOTversion>
    <name>websitename>

    <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
    dependencies>
project>

(3)Controller

@RestController
public class TestController {
    @RequestMapping("/hello")
    public String sayHello(){
        return "hello";
    }
}

注意:
(1) Application类必须在包里面,即开头必须有package。
(2) 和传统的Java EE应用不同,基于Spring Boot框架开发的Web应用程序是自包含的——它不需要部署到应用服务器中,而是自身包含了一个应用服务器。所以我们只要运行Application类中的main()方法即可启动一个Web应用程序。
2、maven安装
在通过Maven构建之前,我们首先需要安装Maven。从这个地址下载Maven,我们只需要下载二进制文件即可,因此我们下载apache-maven-{version}-bin.zip或者apache-maven-{version}-bin.tar.gz文件。下载文件之后将zip包解压到某个目录,将bin文件夹设置到环境变量的path路径中就完成了安装。为了验证Maven是否安装成功,在命令行执行mvn -v命令,如果安装成功,可以看到控制台输出。
mvn compile 编译,将可以在target/classes文件夹下看到编译出来的.class文件。
mvn package 不仅会编译代码,同时会运行所有的测试,最后将target目录下的生成JAR包。
mvn install 不仅编辑、测试和打包,同时将打包出来的制品会复制到本地依赖仓库中。

3、web框架

Spring作为Java系的全栈(full-stack)开发框架,当然也对Web开发有着非常好的支持。Spring的Web Mvc框架能够使开发者非常容易的开发Web应用,同时能够无缝享受到Spring本身的诸多好处——IoC容器、AOP编程等等。它对HTTP请求处理的模型如下图:
这张图重点说明了我们开发Web应用时应该专注于Handle Request的逻辑,也就是根据我们自身业务相关的逻辑代码,而如何监听HTTP请求、处理并将他们返回给浏览器这些非常通用的任务,就交给框架来处理吧。

(1) IOC

先来看看字面上怎么来解释:当一个对象创建时,它所依赖的对象由外部传递给它,而非自己去创建所依赖的对象(比如通过new操作)。因此,也可以说在对象如何获取它的依赖对象这件事情上,控制权反转了。这便不难理解控制反转和依赖注入这两个名字的由来了。

(2) IOC实现

想象一下如果我们自己来实现这个依赖注入的功能,我们怎么来做? 无外乎:
读取标注或者配置文件,看看Boss依赖的是哪个OrderService,拿到类名
使用反射的API,基于类名实例化对应的对象实例
将对象实例,通过构造函数或者setter,传递给Boss
我们发现其实自己来实现也不是很难,Spring实际也就是这么做的。这么看的话其实IoC就是一个工厂模式的升级版!
(3) 面向切面编程(Aspect Oriented Programming,AOP)其实就是一种关注点分离的技术,我们软件开发时经常提一个词叫做“业务逻辑”或者“业务功能”,我们的代码主要就是实现某种特定的业务逻辑。但是我们往往不能专注于业务逻辑,比如我们写业务逻辑代码的同时,还要写事务管理、缓存、日志等等通用化的功能,而且每个业务功能都要和这些业务功能混在一起,痛苦!所以,为了将业务功能的关注点和通用化功能的关注点分离开来,就出现了AOP技术。这些通用化功能的代码实现,对应的就是我们说的切面(Aspect)。切面最终需要合并(专业术语叫做织入, Weave)到业务功能中。怎么做到呢? 这里就涉及AOP的底层技术啦,有三种方式:
编译时织入:在代码编译时,把切面代码融合进来,生成完整功能的Java字节码,这就需要特殊的Java编译器了,AspectJ属于这一类
类加载时织入:在Java字节码加载时,把切面的字节码融合进来,这就需要特殊的类加载器,AspectJ和AspectWerkz实现了类加载时织入
运行时织入:在运行时,通过动态代理的方式,调用切面代码增强业务功能,Spring采用的正是这种方式。动态代理会有性能上的开销,但是好处就是不需要神马特殊的编译器和类加载器啦,按照写普通Java程序的方式来就行了!

@Aspect //1 表示LogAspect是一个切面
@Component
public class LogAspect {

    @Pointcut("execution(* com.tianmaying.aopdemo..*.bookFlight(..))") //2 表示在com.tianmaying.aopdemo包或者子包种调用名称为bookFlight的地方就是切入点
    private void logPointCut() {
    }

    @AfterReturning(pointcut = "logPointCut()", returning = "retVal") //3 表示在bookFlight()调用之后将切面织入
    public void logBookingStatus(boolean retVal) {  //4 定义了实现切面功能的代码
        if (retVal) {
            System.out.println("booking flight succeeded!");
        } else {
            System.out.println("booking flight failed!");
        }
    }
}

注意:要让代码Run起来,还需要在App类中加上@EnableAspectJAutoProxy标注,这样Spring启动时就去去扫描AOP相关的标注,在创建对象时帮我们去执行织入过程!

4、springboot

Spring Boot本身并不提供Spring框架的核心特性以及扩展功能,只是用于快速、敏捷地开发新一代基于Spring框架的应用程序。也就是说,它并不是用来替代Spring的解决方案,而是和Spring框架紧密结合用于提升Spring开发者体验的工具。同时它集成了大量常用的第三方库配置(例如Jackson, JDBC, Mongo, Redis, Mail等等),Spring Boot应用中这些第三方库几乎可以零配置的开箱即用(out-of-the-box),大部分的Spring Boot应用都只需要非常少量的配置代码,开发者能够更加专注于业务逻辑。
@Controller注解表示Application类是一个处理HTTP请求的控制器,该类中所有被@RequestMapping注解的方法都会用来处理对应URL的请求。
@RequestMapping注解可以将URL与处理方法绑定起来。
@ResponseBody注解表示处理函数直接将函数的返回值传回到浏览器端显示。
@RequestParam注解可以解析HTTP请求中Body中的内容
@PathVariable(“variableName”),URL中的变量可以用{variableName}来表示,那么当请求被转发给该方法处理时,对应的URL中的变量会被自动赋值给被@PathVariable注解的参数(能够自动根据参数类型赋值,例如上例中的int)。例:

@RequestMapping("/users/{username}")
public String userProfile(@PathVariable("username") String username) {
    return String.format("user %s", username);
}

(1) 模板返回

将页面的HTML代码写在模板文件中,然后读取该文件并返回。Spring天然支持这种非常常见的场景,需要先在pom.xml引入Thymeleaf依赖。Controller中可以去掉@ResponseBody注解,并将URL处理函数的返回值设为刚刚保存在templates/文件夹中的文件名。Spring框架在发现返回值是”post”后,就会去/templates/目录下读取post.html文件并将它的内容返回给浏览器。

(2) 静态资源

index.html位于templates目录下,通过http://localhost:8080/可以访问首页内容,但是CSS和JavaScript外部资源呢?因为我们的HTTP服务器根本没有处理它们,所以不可能通过类似http://localhost:8080/css/style.css这样的方式来访问它们使得我们的页面正确显示。默认情况下,Spring Boot会将类路径上的/static/目录的内容Serve起来,意思就是所有访问http://localhost:8080/static/**的请求,都会返回/static/目录中对应路径的文件内容,于是我们可以组织src/main/resources目录结构,这个目录经过编译后会被添加到类路径上。
在Web开发中,我们往往需要一种介于相对路径和绝对路径之间的资源访问方式——Context路径:

<link rel="stylesheet" href="/css/style.css"/>
<script src="/js/main.js">script>

这里只是简单的在URL的最前面加上了/,但是意义和相对路径就完全不同了,此时服务器会将其视为访问当前host中的“绝对路径”——也就是自动在这个路径之前添加上协议、主机名和端口(都是当前服务器的相同信息),那么无论我们访问的是当前网站下的任何路径,它都会给出统一的结果。

(3) 模板渲染实现动态页面

抽取出公共部分的内容作为模板,然后根据不同的数据进行渲染,得到不同的输出值。渲染工作就是由本节课的主角——模板引擎来完成的,在Spring Web开发中,我们使用Thymeleaf作为模板引擎。

<div class="blog-post">
  <h3 class="blog-post-title"><a href="#" th:text="${title}">a>h3>
  <p class="blog-post-meta" th:text="${created}">p>
  <p class="blog-post-content" th:text="${content}">p>
div>

th:text=”${title}”就是告诉模板引擎,用title变量作为标签的内容,为了让模板引擎知道title变量的值(created, content也是一样),我们需要在@Controller做一些工作:

@RequestMapping("/posts/{id}")
public String index(@PathVariable("id") long id, Model model) {
    model.addAttribute("title", "This is a post with id = " + id);
    model.addAttribute("created", "2015-08-11");
    model.addAttribute("content", "This is content");
    return "index";
}

通过Spring框架提供的Model,Thymeleaf可以访问它中间的变量从而进行模板渲染。
  如果文章属性很多,每篇文章都要都要addAttribute很多个属性,那将十分麻烦。所以可以直接往Model里面添加对象(此处的Data是一个包含多个Post对象的List的数据类)。

@RequestMapping("/posts/{id}")
public String post(@PathVariable("id") int id, Model model) {
    model.addAttribute("post", Data.getById(id));
    return "post";
}

根据URL中的id获取响应的Post对象,然后交给模板引擎渲染post.html,响应的在模板中的变量表达式也要发生变化:

<div class="blog-post">
  <h3 class="blog-post-title"><a href="#" th:text="${post.title}">a>h3>
  <p class="blog-post-meta" th:text="${post.created}">p>
  <p class="blog-post-content" th:text="${#dates.format(post.created, 'yyyy-MM-dd')}">p>
div>

(4) 提交表单
  HTTP协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。
Spring支持在@RequestMapping注解的方法中使用对象来进行参数绑定,但需要保证类有默认构造函数
(5) 表单验证
数据校验逻辑大多数是通用的,在每一个方法中都编写一个验证逻辑显然是非常重复的。为了解决这个问题,可以使用Java Validation API。

public class Post {

    private static long count = 1;
    private Long id;

    @Size(min=2, max=30)
    private String title;

    @Size(min=1)
    private String content;

    //其余方法、字段省略
}

注解仅仅是对类加上了一些元信息,如果不使用反射等API对其进行探测、处理,和不加注解没有任何区别。所以在@RequestMapping中需要告知Spring框架进行数据校验

@RequestMapping(value = "/", method = RequestMethod.POST)
public String create(@Valid Post post) {
    Data.posts.add(post);
    return "createResult";
}

Spring一旦发现@Valid注解,就会根据Post类中的注解规则进行数据校验。
(6) 页面重定向
 一种叫做Post/Redirect/GET的模式被提出并广泛应用在Web程序开发中。和传统的表单提交方法不同,这种模式在POST请求完成后,会重定向(HTTP状态码302)到另外一个页面。这样相当于浏览器重新加载了一个页面(使用GET请求),此时用户无论如何刷新浏览器,都是刷新当前GET请求对应的页面而不再是重复提交一次表单。

你可能感兴趣的:(个人学习笔记)