欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【Spring实战】笔记——1.Spring起步

程序员文章站 2024-02-15 12:01:17
...

1.1 什么是Spring

**核心:**提供了一个容器(container),通常称为Spring应用上下文(Spring application Context),它们会创建和管理应用组件

**组件:**这些组件称为bean,会在Spring应用上下文中装配在一起,从而形成一个完整的应用程序。

**装配:**将bean装配在一起的行为是通过一种基于依赖注入(dependency injection,DI)的模式实现的。此时,组件不再去创建它所依赖的组件并管理它们的生命周期,而是使用依赖注入的应用依赖于单独的实体(容器)来创建和维护所有的组件,并将其注入到需要它们的bean中。通常通过构造器参数和属性访问方式来实现。

Spring的装配方式:

  • 使用一个或多个XML文件:

    <bean id="inventoryService" class="com.example.InventryService"/>
    <bean id="productService" class="com.example.ProductService"/>
    <constructor-arg ref="imventoryService"/>
    </bean>
    
  • 基于Java的配置类:

    @Configuration
    public class ServiceConfiguration {
        @Bean
        public InventoryService inventoryService() {
            return new InventotyService();
        }
        @Bean
        public ProductService productService() {
            return new ProductService(inventoryService());
        }
    }
    

    @Configuration 注解会告知Spring这是一个配置类,会为Spring应用上下文提供bean。这个配置类的方法使用**@Bean**注解进行了标注,表明这些方法所返回的对象会以bean的形式添加到Spring的应用上下文中。

  • 自动配置

    不管是Java配置还是xml配置,只有当Spring不能进行自动配置时才是必要的。

    自动配置起源于所谓的自动装配(autowiring)和组件扫描(component scanning)。

    • 组件扫描技术:自动发现应用类路径下的组件,并为它们创建成Spring应用上下文中的bean
    • 自动装配技术:Spring能够自动为组件注入它们所依赖的其他bean

    随着SpringBoot的引入,自动配置的能力已经远远超出了组件扫描和自动装配。

SpringBoot

SpringBoot是Spring框架的扩展,提供了很多增强生产效率的方法。能够基于类路径中的条目、环境变量和其他因素合理猜测需要配置的组件并将它们装配在一起。

1.2 初始化Spring应用

1.2.1 初始化Spring项目

1.创建project,选择Spring Initializr
【Spring实战】笔记——1.Spring起步

【Spring实战】笔记——1.Spring起步

3.选择依赖,目前只需要这三个,可以从搜索框搜索
【Spring实战】笔记——1.Spring起步

1.2.2 检查项目结构

【Spring实战】笔记——1.Spring起步

  • **src/main/java:**应用的源码

  • **src/test/java:**测试代码

  • **src/main/resources:**非Java资源

  • mvnw和mvnw.cmd:这是Maven包装器(wrapper)脚本。借助这些脚本,即便你的机器上没有安装Maven,也可以构建项目。

  • pom.xml:Maven构建规范。

  • xxxApplication.java:这是Spring Boot主类,它会启动该项目。

  • application.properties:这个文件起初是空的,但是它为我们提供了指定配置属性的地方。

  • static:在这个文件夹下,你可以存放任意为浏览器提供服务的静态内容(图片、样式表、JavaScript等),该文件夹初始为空。

  • templates:这个文件夹中存放用来渲染内容到浏览器的模板文件

  • xxxApplicationTests.java:这是一个简单的测试类,它能确保Spring应用上下文可以成功加载。

探索构建规范

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
  1. 代码第14行:<packaging>,选择将应用构建为jar,而不是war。(如果没有这行代码可以自己加上)

    ​ 通常,传统的Java web应用都是打包成war文件,而jar只是用来打包库和较为少见的桌面UI应用的。

    ​ 打包为jar文件是基于云思维做出的选择,尽管war文件非常适合部署到传统的Java应用服务器上,但对于大多数云平台来说它们并不是理想的选择。有些云平台也能够部署和运行war文件,但是所有的Java云平台都能够运行可执行的jar文件。

    ​ 如果想要将应用部署到传统的Java应用服务器上,那么需要选择使用基于war的打包方式并要包含一个web初始化类。(后面会提到)

  2. 第5行:<parent>元素

    <artifactId>表明我们的项目要以spring-boot-starter-parent作为其父POM。除了其他的一些功能之外,这个父POM为Spring项目常用的一些库提供了依赖管理。

    <version>表明版本。会由这个版本的SpringBoot定义来继承依赖管理。

  3. 第22行:`````元素声明了几个依赖。

    这些依赖的<artifact ID>上都有spring-boot-starter。spring-boot-starter依赖的特别之处在于它们本身并不包含库代码,而是传递性地拉取其他的库。这种依赖有3个好处:

    • 构建文件会显著减小并且更易于管理,因为不必为每个所需的依赖库都
      声明依赖
    • 我们能够根据它们所提供的功能来思考依赖,而不是根据库的名称。
    • 我们不必再担心库版本的问题,你可以直接相信给定版本的SpringBoot,传递性引入的库的版本是兼容的。
  4. 最后,构建规范还包含一个SpringBoot插件。这个插件提供了一些重要的功能:

    • 提供了一个Maven goal,允许我们使用Maven来运行应用。
    • 会确保依赖的所有库都会包含在可执行的JAR文件中,并且能够保证它们在运行时类路径下是可用的
    • 会在JAR中生成一个manifest文件,将引导类声明为可执行的JAR的主类。

引导应用

DemoApplication.java

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

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

}
  1. @SpringBootApplication是一个组合注解,它组合了3个其他的注解。

    • @SpringBootConfiguration:将该类声明为配置类。
    • @EnableAutoConfiguration:启用SpringBoot的自动配置。
    • @ComponentScan:启用组件扫描。我们可以通过像@Component、@Controller、@Services这样的注解声明其他类,Spring会自动发现它们并将它们注册为Spring应用上下文中的组件
  2. main()方法。这是JAR文件执行的时候要运行的方法。

    ​ 这个main()方法会调用SpringApplication中静态的run()方法,后者会真正执行应用的引导过程,也就是创建Spring的应用上下文。在传递给run()的两个参数中,一个是配置类,另一个是命令行参数。

测试应用

DemoApplicationTests

package com.example.demo;

import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
class DemoApplicationTests {

    @Test
    void contextLoads() {
    }

}

1.3 编写Spring应用

为Demo应用添加一个主页:

  • 一个控制器类,用来处理主页相关的请求
  • 一个视图模板,用来定义主页的内容
  • 一个简单的测试类

1.3.1 处理Web请求

Spring自带一个强大的web框架——Spring MVC

SpringMVC的核心是==控制器(Controller)==理念。控制器是处理请求并以某种方式进行信息响应的类。在面向浏览器的应用中,控制器会填充可选的数据模型,并将请求传递给一个视图,以便于生成返回给浏览器的HTML。

主页控制器:编写一个简单的控制器类以处理对根路径(“/”)的请求,并将请求转发至主页视图。

package com.example.demo;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {
    @GetMapping("/")
    public String home() {
        return "home";
    }
}

@Controller的主要目的是让组件扫描并将这个类识别为一个组件。Spring的组件扫描功能会自动发现HomeController,并创建一个HomeController实例作为Spring应用上下文中的bean。

home()是一个简单的控制器方法。它带有@GetMapping注解,表明如果针对“/”发送HTTP GET请求,那么这个方法将会处理请求。该方法所做的只是返回String类型的home值。

这个值将会被解析为视图的逻辑名。

1.3.2 定义视图

【Spring实战】笔记——1.Spring起步

home.html

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
</head>
<body>
	<h1>Welcome to ...</h1>
	<img th:src="@{/image/001.png}" alt="">
</body>
</html>

第9行:<img>标签使用了Thymeleaf的th:src属性和@{…}表达式,以便于引用相对于上下文路径的图片。

图片是相对于上下文的/image/001.png/image/001.png路径来进行引用的。图片这样的静态资源是放到/src/main/resources/static/src/main/resources/static文件夹中的。这意味着图片必须要位于/src/main/resources/static/image/001.png/src/main/resources/static/image/001.png

1.3.3 测试控制器

HomeControllerTest

package com.example.demo;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;

import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@RunWith(SpringRunner.class)
@WebMvcTest(HomeController.class)
public class HomeControllerTest {
    @Autowired
    private MockMvc mockMvc;

    @Test
    public void testHomePage() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.get("/"))
                .andExpect(status().isOk())
                .andExpect(view().name("home"))
                .andExpect(content().string(
                        containsString("Welcome to...")
                ));
    }

}

22行mockMvc.perform(MockMvcRequestBuilders.get("/"))

原书为mockMvc.perform(get(“/”)),并import import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;,我尝试后不行,所以做出了更改

HomeControllerTest没有使用@SpringBootTest标记,而是使用了@WebMvcTest注解。这是SpringBoot所提供的一个特殊测试注解,会让测试在SpringMVC应用的上下文中执行。

@WebMvcTest同样会为测试SpringMVC应用提供Spring环境的支持。测试类被注入了一个MockMvc,能够让测试实现mockup。

通过testHomePage()方法,我们定义了针对主页想要执行的测试。它首先使用了MockMvc对象对“/”(根路径)发起了HTTP GET请求。对于这个请求,我们设置了如下的预期:

  • 响应应该具备HTTP 200 (OK)状态;
  • 视图的逻辑名称应该是home;
  • 渲染后的视图应该包含文本“Welcome to…”。
相关标签: Spring实战