Spring Boot入门

SpringBoot快速入门(转载)

创建 SpringBoot 项目(IDEA)

使用 Spring Initializr 创建

新建项目,进行如图配置

image-20220529112153248

下一步,选择 SpringBoot 版本,搜 Web,添加 Spring Web 依赖

image-20220529112416519

点击完成,等待 maven 依赖导入完成,SpringBoot启动类就可以运行了。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fAxhJU2s-1655976160769)(https://gitee.com/zhang-rui-xin/image/raw/master/image-20220623164623428.png)]

运行 SpringBootDemoApplication

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NV7w6OZX-1655976160769)(https://gitee.com/zhang-rui-xin/image/raw/master/image-20220529113407140.png)]

包下新建一个 controller (Java包的命名规范,包名都用小写)包,controller 包下新建一个 HelloController 类,输入一下内容

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

本地浏览器访问 localhost:8080/hello,看到浏览器显示 Hello World,表示运行成功

YAML入门

SpringBoot 默认使用以下 2 种全局的配置文件,其文件名是固定的。

  • ​ application.properties
  • ​ application.yml
YAML简介

YAML 全称 YAML Ain’t Markup Language,它是一种以数据为中心的标记语言,比 XML 和 JSON 更适合作为配置文件。

举个栗子:

server:
  port: 8080

该例设置了服务器端口

YAML语法

YAML 的语法如下:

  • ​ 使用缩进表示层级关系。
  • ​ 缩进时不允许使用 Tab 键,只允许使用空格。
  • ​ 缩进的空格数不重要,但同级元素必须左侧对齐。
  • ​ 大小写敏感。
YAML其他规范访问原文官网:http://c.biancheng.net/spring_boot/yaml.html

Spring Boot 配置绑定

SpringBoot 提供了以下 2 种方式进行配置绑定:

  • ​ 使用 @ConfigurationProperties 注解
  • ​ 使用 @Value 注解
@ConfigurationProperties

使用该注解前,先引入该注解处理器依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

通过 Spring Boot 提供的 @ConfigurationProperties 注解,可以将全局配置文件中的配置数据绑定到 JavaBean 中。下面我们以 Spring Boot 项目 helloworld 为例,演示如何通过 @ConfigurationProperties 注解进行配置绑定。

1. 在 helloworld 的全局配置文件 application.yml 中添加以下自定义属性。
person:
  lastName: 张三
  age: 18
  boss: false
  birth: 1990/12/12
  maps: { k1: v1,k2: 12 }
  lists:
    ‐ lisi
    ‐ zhaoliu
  dog:
    name: 迪迪
    age: 5
2. 创建一个名为 Person 的实体类,并将配置文件中的属性映射到这个实体类上,代码如下。
/**
    * 将配置文件中配置的每一个属性的值,映射到这个组件中
    *
    * @ConfigurationProperties:告诉 SpringBoot 将本类中的所有属性和配置文件中相关的配置进行绑定;
    * prefix = "person":配置文件中哪个下面的所有属性进行一一映射
    *
    * 只有这个组件是容器中的组件,才能使用容器提供的@ConfigurationProperties功能;
    */
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
    private String lastName;
    private Integer age;
    private Boolean boss;
    private Date birth;
    private Map<String, Object> maps;
    private List<Object> lists;
    private Dog dog;
    public Person() {
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public Boolean getBoss() {
        return boss;
    }
    public void setBoss(Boolean boss) {
        this.boss = boss;
    }
    public Date getBirth() {
        return birth;
    }
    public void setBirth(Date birth) {
        this.birth = birth;
    }
    public Map<String, Object> getMaps() {
        return maps;
    }
    public void setMaps(Map<String, Object> maps) {
        this.maps = maps;
    }
    public List<Object> getLists() {
        return lists;
    }
    public void setLists(List<Object> lists) {
        this.lists = lists;
    }
    public Dog getDog() {
        return dog;
    }
    public void setDog(Dog dog) {
        this.dog = dog;
    }
    public Person(String lastName, Integer age, Boolean boss, Date birth, Map<String, Object> maps, List<Object> lists, Dog dog) {
        this.lastName = lastName;
        this.age = age;
        this.boss = boss;
        this.birth = birth;
        this.maps = maps;
        this.lists = lists;
        this.dog = dog;
    }
    @Override
    public String toString() {
        return "Person{" +
            "lastName='" + lastName + '\'' +
            ", age=" + age +
            ", boss=" + boss +
            ", birth=" + birth +
            ", maps=" + maps +
            ", lists=" + lists +
            ", dog=" + dog +
            '}';
    }
}

注意:

1、使用 @Component 注解标注实体类,让该类处于 IOC ( Spring 知识 )容器中,才能享受 Spring Boot 的强大功能。

2、JavaBean 标识了 @ConfigurationProperties(prefix = ‘person’),表示将 JavaBean 中的所有属性与配置文件中以“person”为前缀的配置进行绑定

3、创建一个名为 Dog 的 JavaBean

public class Dog {
    private String name;
    private String age;
    public Dog() {
    }
    public Dog(String name, String age) {
        this.name = name;
        this.age = age;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setAge(String age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public String getAge() {
        return age;
    }
}
4、修改 HelloController 的代码
@RestController
public class HelloController {

    @Autowired
    private Person person;

    @RequestMapping("/hello")
    public Person sayHello(){
        return person;
    }

}
5、重启项目,使用浏览器访问 “http://localhost:8080/hello”

运行结果:

image-20220529131235014
@Value

当我们只需要读取配置文件中的某一个配置时,可以通过 @Value 注解获取。

修改 Person 类的内容

@Component
public class Person {
    @Value("${person.lastName}")
    private String lastName;
    @Value("${person.age}")
    private Integer age;
    @Value("${person.boss}")
    private Boolean boss;
    @Value("${person.birth}")
    private Date birth;
    private Map<String, Object> maps;
    private List<Object> lists;
    private Dog dog;
    public Person() {
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public Boolean getBoss() {
        return boss;
    }
    public void setBoss(Boolean boss) {
        this.boss = boss;
    }
    public Date getBirth() {
        return birth;
    }
    public void setBirth(Date birth) {
        this.birth = birth;
    }
    public Map<String, Object> getMaps() {
        return maps;
    }
    public void setMaps(Map<String, Object> maps) {
        this.maps = maps;
    }
    public List<Object> getLists() {
        return lists;
    }
    public void setLists(List<Object> lists) {
        this.lists = lists;
    }
    public Dog getDog() {
        return dog;
    }
    public void setDog(Dog dog) {
        this.dog = dog;
    }
    public Person(String lastName, Integer age, Boolean boss, Date birth, Map<String, Object> maps, List<Object> lists, Dog dog) {
        this.lastName = lastName;
        this.age = age;
        this.boss = boss;
        this.birth = birth;
        this.maps = maps;
        this.lists = lists;
        this.dog = dog;
    }
    @Override
    public String toString() {
        return "Person{" +
                "lastName='" + lastName + '\'' +
                ", age=" + age +
                ", boss=" + boss +
                ", birth=" + birth +
                ", maps=" + maps +
                ", lists=" + lists +
                ", dog=" + dog +
                '}';
    }
}
@Value 与 @ConfigurationProperties 对比

@Value 和 @ConfigurationProperties 注解都能读取配置文件中的属性值并绑定到 JavaBean 中,但两者存在以下不同。

1. 使用位置不同
  • ​ @ConfigurationProperties:标注在 JavaBean 的类名上;
  • ​ @Value:标注在 JavaBean 的属性上。
2. 功能不同
  • ​ @ConfigurationProperties:用于批量绑定配置文件中的配置;
  • ​ @Value:只能一个一个的指定需要绑定的配置。
3. 松散绑定支持不同

@ConfigurationProperties:支持松散绑定(松散语法),例如实体类 Person 中有一个属性为 firstName,那么配置文件中的属性名支持以下写法:

  • ​ person.firstName
  • ​ person.first-name
  • ​ person.first_name
  • ​ PERSON_FIRST_NAME


@Vaule:不支持松散绑定。

4. SpEL 支持不同
  • ​ @ConfigurationProperties:不支持 SpEL 表达式;
  • ​ @Value:支持 SpEL 表达式。
5. 复杂类型封装
  • ​ @ConfigurationProperties:支持所有类型数据的封装,例如 Map、List、Set、以及对象等;
  • ​ @Value:只支持基本数据类型的封装,例如字符串、布尔值、整数等类型。
6. 应用场景不同

​ @Value 和 @ConfigurationProperties 两个注解之间,并没有明显的优劣之分,它们只是适合的应用场景不同而已。

  • ​ 若只是获取配置文件中的某项值,则推荐使用 @Value 注解;
  • ​ 若专门编写了一个 JavaBean 来和配置文件进行映射,则建议使用 @ConfigurationProperties 注解。

我们在选用时,根据实际应用场景选择合适的注解能达到事半功倍的效果。

原文链接:http://c.biancheng.net/spring_boot/config-bind.html

@PropertySource

如果将所有的配置都集中到 application.properties 或 application.yml 中,那么这个配置文件会十分的臃肿且难以维护,因此我们通常会将与 Spring Boot 无关的配置(例如自定义配置)提取出来,写在一个单独的配置文件中,并在对应的 JavaBean 上使用 @PropertySource 注解指向该配置文件。

1、以 helloworld 为例,将与 person 相关的自定义配置移动到 src/main/resources 下的 person.properties 中(注意,必须把 application.properties 或 application.yml 中的相关配置删除),如下图。

image-20220529144449326
person.last-name=李四
person.age=12
person.birth=2000/12/15
person.boss=false
person.maps.k1=v1
person.maps.k2=14
person.lists=a,b,c
person.dog.name=dog
person.dog.age=2

2、在 Person 使用 @PropertySource 注解指向 person.properties,代码如下。

@PropertySource(value = "classpath:person.properties")//指向对应的配置文件
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
    private String lastName;
    private Integer age;
    private Boolean boss;
    private Date birth;
    private Map<String, Object> maps;
    private List<Object> lists;
    private Dog dog;
    public Person() {
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public Boolean getBoss() {
        return boss;
    }
    public void setBoss(Boolean boss) {
        this.boss = boss;
    }
    public Date getBirth() {
        return birth;
    }
    public void setBirth(Date birth) {
        this.birth = birth;
    }
    public Map<String, Object> getMaps() {
        return maps;
    }
    public void setMaps(Map<String, Object> maps) {
        this.maps = maps;
    }
    public List<Object> getLists() {
        return lists;
    }
    public void setLists(List<Object> lists) {
        this.lists = lists;
    }
    public Dog getDog() {
        return dog;
    }
    public void setDog(Dog dog) {
        this.dog = dog;
    }
    public Person(String lastName, Integer age, Boolean boss, Date birth, Map<String, Object> maps, List<Object> lists, Dog dog) {
        this.lastName = lastName;
        this.age = age;
        this.boss = boss;
        this.birth = birth;
        this.maps = maps;
        this.lists = lists;
        this.dog = dog;
    }
    @Override
    public String toString() {
        return "Person{" +
                "lastName='" + lastName + '\'' +
                ", age=" + age +
                ", boss=" + boss +
                ", birth=" + birth +
                ", maps=" + maps +
                ", lists=" + lists +
                ", dog=" + dog +
                '}';
    }
}
image-20220529144731031
@ConfigurationProperties / @Value 读取 properties 文件乱码

在 idea 设置中将这些编码格式都设置为 UTF-8

image-20220529145453599

再从 @PropertySource 中也设置字符编码格式( encoding )为 UTF-8

@PropertySource(value = "classpath:person.properties" , encoding = "UTF-8")

Spring Boot 导入 Spring 配置

@ImportResource 导入 Spring 配置文件

在主启动类上使用 @ImportResource 注解可以导入一个或多个 Spring 配置文件,并使其中的内容生效。

1、新建 PersonService 接口并将其实现

public interface PersonService {
    public Person getPersonInfo();
}
public class PersonServiceImpl implements PersonService {
    @Autowired
    private Person person;
    @Override
    public Person getPersonInfo() {
        return person;
    }
}

**2、在 resources 下添加一个名为 beans.xml 的 Spring 配置文件 **

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="personService" class="com.example.spring_boot_demo.service.impl.PersonServiceImpl"/>
   
</beans>

3、创建测试类,引入IOC容器测试

@SpringBootTest
public class PersonServiceTest {

    //IOC容器
    @Autowired
    ApplicationContext ioc;

    @Test
    public void testHelloService() {
        //校验 IOC 容器中是否包含组件 personService
        boolean b = ioc.containsBean("personService");
        if (b) {
            System.out.println("personService 已经添加到 IOC 容器中");
        } else {
            System.out.println("personService 没添加到 IOC 容器中");
        }
    }

}

(未添加 @ImportResource 注解)运行:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jBEc57ik-1655976160770)(https://gitee.com/zhang-rui-xin/image/raw/master/image-20220529153143231.png)]

4、在主启动类上添加 @ImportResource 注解,将 Spring 配置文件 beans.xml 添加到项目

@ImportResource(locations = {"classpath:/beans.xml"})
@SpringBootApplication
public class SpringBootDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootDemoApplication.class, args);
    }
}

再次运行测试方法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WVrb9jli-1655976160771)(https://gitee.com/zhang-rui-xin/image/raw/master/image-20220529154020675.png)]

成功将 Spring 配置文件加入项目

全注解方式:请参考原文:http://c.biancheng.net/spring_boot/import-spring-config.html

Spring Boot Profile (多环境)

多 Profile 文件方式

properties 配置

创建 4 个配置文件:

  • ​ application.properties:主配置文件
  • ​ application-dev.properties:开发环境配置文件
  • ​ application-test.properties:测试环境配置文件
  • ​ application-prod.properties:生产环境配置文件

在 application.properties 文件中,指定默认服务器端口号为 8080,并通过以下配置激活生产环境(prod)的 profile。

#默认端口号
server.port=8080
#激活指定的profile
spring.profiles.active=prod

在 application-dev.properties 中,指定开发环境端口号为 8081,配置如下

# 开发环境
server.port=8081

在 application-test.properties 中,指定测试环境端口号为 8082,配置如下。

# 测试环境
server.port=8082

在 application-prod.properties 中,指定生产环境端口号为 8083,配置如下。

# 生产环境
server.port=8083

重启 Spring Boot 主启动程序,控制台输出如下图。

image-20220529160701106

通过上图可以看到,我们指定的生产环境(prod) Profile 生效了,且服务器端口为 8083。

多 Profile 文档块模式
详细请参考原文:http://c.biancheng.net/spring_boot/profile.html

Spring Boot 默认配置文件

默认配置文件

Spring Boot 项目中可以存在多个 application.properties 或 apllication.yml。

Spring Boot 启动时会扫描以下 5 个位置的 application.properties 或 apllication.yml 文件,并将它们作为 Spring boot 的默认配置文件。

  1. ​ file:./config/*/
  2. ​ file:./config/
  3. ​ file:./
  4. ​ classpath:/config/
  5. ​ classpath:/

​ 注:file: 指当前项目根目录;classpath: 指当前项目的类路径,即 resources 目录。

以上所有位置的配置文件都会被加载,且它们优先级依次降低,序号越小优先级越高。其次,位于相同位置的 application.properties 的优先级高于 application.yml。

所有位置的文件都会被加载,高优先级配置会覆盖低优先级配置,形成互补配置,即:

  • ​ 存在相同的配置内容时,高优先级的内容会覆盖低优先级的内容;
  • ​ 存在不同的配置内容时,高优先级和低优先级的配置内容取并集。

参考原文:http://c.biancheng.net/spring_boot/default-config.html

Spring Boot 日志

SLF4J 的使用
public class HelloWorld {
    public static void main(String[] args) {
        Logger logger = LoggerFactory.getLogger(HelloWorld.class);
       //调用 sl4j 的 info() 方法,而非调用 logback 的方法
        logger.info("Hello World");
    }
}

注解使用方法:import lombok.extern.slf4j.Slf4j;

打个 @Slf4j 注解,通过 log.info() 记录日志

@RestController
@Slf4j
public class HelloController {

    @Autowired
    private Person person;

    @RequestMapping("/hello")
    public Person sayHello(){
        log.info("Hello World!~");
        return person;
    }

}
日志级别

日志的输出都是分级别的,当一条日志信息的级别大于或等于配置文件的级别时,就对这条日志进行记录。

常见的日志级别如下(优先级依次升高)。

序号日志级别说明
1trace追踪,指明程序运行轨迹。
2debug调试,实际应用中一般将其作为最低级别,而 trace 则很少使用。
3info输出重要的信息,使用较多。
4warn警告,使用较多。
5error错误信息,使用较多。

Thymeleaf

Spring Boot 整合 Thymeleaf ,引入依赖:

<!--Thymeleaf 启动器-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

ThymeleafAutoConfiguration 使用 @EnableConfigurationProperties 注解导入了 ThymeleafProperties 类,该类包含了与 Thymeleaf 相关的自动配置属性,其部分源码如下。

@ConfigurationProperties(
    prefix = "spring.thymeleaf"
)
public class ThymeleafProperties {
    private static final Charset DEFAULT_ENCODING;
    public static final String DEFAULT_PREFIX = "classpath:/templates/";
    public static final String DEFAULT_SUFFIX = ".html";
    private boolean checkTemplate = true;
    private boolean checkTemplateLocation = true;
    private String prefix = "classpath:/templates/";
    private String suffix = ".html";
    private String mode = "HTML";
    private Charset encoding;
    private boolean cache;
    ...
}

由此可知,只需要将 HTML 页面放在 “classpath:/templates/” 中,Thymeleaf 就能够自动进行渲染

例如:

1、创建一个名为 hello.html 的页面,并将该页面放在项目类路径(resources)下的 templates 目录中,hello.html 代码如下。

<!DOCTYPE html>
<!--导入thymeleaf的名称空间-->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <!--th:text 为 Thymeleaf 属性,用于获取指定属性的值-->
        <h1 th:text="'欢迎来到'+${name}"></h1>
    </body>
</html>

3、新建一个控制类 HelloController,并通过参数 map 传递数据到前台页面中,代码如下。

@Controller
public class HelloController {
    @RequestMapping("/hello")
    public String hello(Map<String, Object> map) {
        //通过 map 向前台页面传递数据
        map.put("name", "德莱联盟");
        return "hello";
    }
}

运行结果:

image-20220529200947319

Spring Boot 拦截器

在 Spring Boot 项目中,使用拦截器功能通常需要以下 3 步:

  1. ​ 定义拦截器;
  2. ​ 注册拦截器;
  3. ​ 指定拦截规则(如果是拦截所有,静态资源也会被拦截)。
定义拦截器

创建一个拦截器类,实现 HandlerInterceptor 接口即可

HandlerInterceptor 中定义了三个方法:

  • preHandle (HttpServletRequest request, HttpServletResponse response, Object handler)

​ 该方法在控制器处理请求方法之前执行,返回 true 表示继续执行,返回 false 表示中断后续操作

  • postHandle (HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)

​ 该方法在控制器处理请求方法调用之后、解析视图之前执行,可以通过此方法对请求域中的模型和视图做进一步修改。

  • afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)

    该方法在视图渲染结束后执行,可以通过此方法实现资源清理、记录日志信息等工作

@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
    /**
     * 目标方法执行前
     *
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Object loginUser = request.getSession().getAttribute("loginUser");
        if (loginUser == null) {
            //未登录,返回登陆页
            request.setAttribute("msg", "您没有权限进行此操作,请先登陆!");
            request.getRequestDispatcher("/index.html").forward(request, response);
            return false;
        } else {
            //放行
            return true;
        }
    }
    /**
     * 目标方法执行后
     *
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("postHandle执行{}", modelAndView);
    }
    /**
     * 页面渲染后
     *
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("afterCompletion执行异常{}", ex);
    }
}

request, response);
return false;
} else {
//放行
return true;
}
}
/**
* 目标方法执行后
*
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.info(“postHandle执行{}”, modelAndView);
}
/
*
* 页面渲染后
*
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
log.info(“afterCompletion执行异常{}”, ex);
}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值