Spring Boot 快速入门(一)

为什么使用SpringBoot

Spring的缺点:

  • 复杂的配置: 配置十分繁琐,项目的环境配置会增加开发时的损耗,开发者在思考 Spring 特性配置和解决业务问题之间需要进行思维切换,环境配置会占用写应用程序逻辑的时间。

  • 依赖管理: 项目的依赖管理也是一件耗时耗力的事情。在环境搭建时,需要分析要导入哪些库的坐标,而且还需要分析导入与之有依赖关系的其他库的坐标,并且,依赖管理也是一种损耗,添加依赖不是写应用程序代码。一旦选错了依赖的版本,随之而来的不兼容问题就会严重阻碍项目的开发进度。

SpringBoot解决了上述Spring的缺点:

SpringBoot是Spring项目中的一个子工程,它对上述Spring的缺点进行的改善和优化,基于约定优于配置的思想,可以让开发人员不必在配置与逻辑业务之间进行思维的切换,全身心的投入到逻辑业务的代码编写中,从而大大提高了开发的效率,一定程度上缩短了项目周期。
在这里插入图片描述

SpringBoot的特点:

  • 创建独立的spring应用程序
  • 直接内嵌tomcat、jetty和undertow(不需要打包成war包部署)
  • 提供了固定化的“starter”配置,以简化构建配置
  • 尽可能的自动配置spring和第三方库
  • 提供产品级的功能,如:安全指标、运行状况监测和外部化配置等
  • 绝对不会生成代码,并且不需要XML配置

人们把Spring Boot称为搭建程序的脚手架。它能帮我们快速的构建庞大的spring项目,并且尽可能的减少一切xml配置,这样我们在开发时关注点集中在了业务问题上,而不再是配置问题上,可以非常轻松的开始应用程序。

SpringBoot的核心功能

  • 起步依赖: 起步依赖本质上是一个Maven项目对象模型(Project Object Model,POM),定义了对其他库的传递依赖,这些东西加在一起即支持某项功能。 简单的说,起步依赖就是将具备某种功能的坐标打包到一起,并提供一些默认的功能。
  • 自动配置: Spring Boot的自动配置是一个运行时(更准确地说,是应用程序启动时)的过程,考虑了众多因素,才决定Spring配置应该用哪个,不该用哪个。该过程是Spring自动完成的。

SpringBoot 快速入门

项目结构:
在这里插入图片描述

1. 创建一个Maven工程,在pom.xml中导入Spring Boot相关的依赖:

创建工程:
首先File->new Project,选择Maven工程,这里不需要勾选Create from archetype,
在这里插入图片描述
点击next之后,配置自己的工程名称,点击finish
在这里插入图片描述

引入依赖:
找到项目目录中的pom.xml配置文件,所有的springboot的工程都以spring父工程为父工程,我们必须进行配置,父工程:spring-boot-starter-parent,如果我们要进行web开发还要配置web功能的起步依赖spring-boot-starter-web

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <!--配置父工程,导入下面的配置就表示这是一个springboot的项目-->
    <!--这个父工程的目的就是依赖般的锁定-->
    <!--所有的springboot的工程都以spring父工程为父工程,必须继承spring-boot-starter-parent -->
    <parent>
        <artifactId>spring-boot-starter-parent</artifactId>
        <groupId>org.springframework.boot</groupId>
        <version>2.0.1.RELEASE</version>
    </parent>

    <groupId>org.example</groupId>
    <artifactId>SpringBoot_quick</artifactId>
    <version>1.0-SNAPSHOT</version>


    <dependencies>
        <!--web功能的起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>

        <!--@ConfiguaritionProperties的执行器配置:根据配置文件时,给出对应提示-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

    </dependencies>

</project>

在SpringBoot的父工程(spring-boot-starter-parent)中已经对大部分常用依赖的版本进行了管理,我们不需要操心依赖的版本问题了,需要什么依赖,直接引入坐标即可!

2. 配置启动项

创建SpringbootTestApplication类,作为我们的启动项 ,需要添加@SpringBootApplication注解

//声明类是一个SpringBoot引导类
@SpringBootApplication
public class MySpringBootApplication {

    //main是Java程序的入口
    public static void main(String[] args){
        //run方法 表示运行springboot的引导   run参数就是SpringBoot引导类的字节码对象
        SpringApplication.run(MySpringBootApplication.class,args);
    }

}

启动测试:
在这里插入图片描述

创建Controller测试在web浏览器中打开

@Controller
public class TestController {

    @RequestMapping("/test")
    @ResponseBody
    public String quick(){
        return "Hello SpringBoot";
    }
}


@RestController  // 使用该注解后不需要再使用@ResponseBody注解
public class TestController {

    @RequestMapping("/test")
    public String quick(){
        return "Hello SpringBoot";
    }
}

在页面访问 http://localhost:8080/test ,访问成功!
在这里插入图片描述

SpringBoot工程的热部署:
在我们开发过程中会频繁修改类或页面中的信息,而每次修改过后都要重新启动才能生效,非常麻烦,通过热部署的方式,可以让我们在修改过代码之后不需要重启就能生效,相关配置如下:

<!--@ConfiguaritionProperties的执行器配置:根据配置文件时,给出对应提示-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

在配置过后,还需要对IDEA进行自动编译设置:Settings->Build->Compiler,勾选Build project automatically
在这里插入图片描述
使用快捷键Shift+Ctrl+Alt+/,选择Registry...
在这里插入图片描述
勾选compiler.automake.allow.when.app.running
在这里插入图片描述

使用IDEA快速搭建SpringBoot工程:

1. 新建工程,选择Spring Initializr,这里可以选择默认的URL: https://start.spring.io,如果构建过程中出现问题可以选择阿里云的URL:https://start.aliyun.com/
在这里插入图片描述
2.创建项目,注意这里Artifact名称只能是全大写或全小写
在这里插入图片描述
3. 添加相关模板引擎
在这里插入图片描述
4. 搭建完成,测试运行
在这里插入图片描述

SpringBoot原理分析

1. 起步依赖原理分析

在这里插入图片描述

分析spring-boot-starter-parent:
按住Ctrl点击pom.xml中的spring-boot-starter-parent,跳转到了spring-boot-starter-parent的pom.xml,xml配置如下:

在这里插入图片描述

按住Ctrl点击pom.xml中的spring-boot-starter-dependencies,跳转到了spring-boot-starter-dependencies的pom.xml,xml配置如下:
在这里插入图片描述

在这里插入图片描述

从上图中我们可以看到,一部分坐标的版本、依赖管理、插件管理已经定义好,所以我们的SpringBoot工程继承spring-boot-starter-parent后已经具备版本锁定等配置了,所以起步依赖的作用就是进行依赖的传递。

2. 分析spring-boot-starter-web

启动器:为了让SpringBoot帮我们完成各种自动配置,我们必须引入SpringBoot提供的自动配置依赖,我们称为启动器。spring-boot-starter-parent工程将依赖关系声明为一个或者多个启动器,我们可以根据项目需求引入相应的启动器,因为我们是web项目,这里我们引入web启动器:

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

在上方代码中,并没有在这里指定版本信息,因为SpringBoot的父工程已经对版本进行了管理了。SpringBoot会根据spring-boot-starter-web这个依赖自动引入的,而且所有的版本都已经管理好,不会出现冲突。接下来我们可以查看以下代码:按住Ctrl点击pom.xml中的spring-boot-starter-web,跳转到了spring-boot-starter-web的pom.xml,观察xml中的配置(只摘抄了部分重点配置):

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  
  、、、、、、、、、
  
  <dependencies>
   
    、、、、、、、、、、
   
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.0.5.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.0.5.RELEASE</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>
</project>

从上面的spring-boot-starter-web的pom.xml中我们可以发现,spring-boot-starter-web就是将web开发要使用的spring-web、spring-webmvc等坐标进行了“打包”,这样我们的工程只要引入spring-boot-starter-web起步依赖的坐标就可以进行web开发了,同样体现了依赖传递的作用。

2. 自动配置原理分析

使用Ctrl点击查看启动类上的注解@SpringBootApplication

//声明类是一个SpringBoot引导类
@SpringBootApplication
public class MySpringBootApplication {

    //main是Java程序的入口
    public static void main(String[] args){
        //run方法 表示运行springboot的引导   run参数就是SpringBoot引导类的字节码对象
        SpringApplication.run(MySpringBootApplication.class);
    }

}

发现@SpringBootApplication其实是一个组合注解,这里重点的注解有3个:

  • @SpringBootConfiguration:声明配置类
  • @EnableAutoConfiguration:开启自动配置
  • @ComponentScan:开启注解扫描(扫描与其同级)
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
    @AliasFor(
        annotation = EnableAutoConfiguration.class
    )
    Class<?>[] exclude() default {};

    @AliasFor(
        annotation = EnableAutoConfiguration.class
    )
    String[] excludeName() default {};

    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "basePackages"
    )
    String[] scanBasePackages() default {};

    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "basePackageClasses"
    )
    Class<?>[] scanBasePackageClasses() default {};
}

@SpringBootConfiguration中的代码:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}

通过这段代码中我们可以看出,该注解中还是应用了@Configuration这个注解。其作用就是声明当前类是一个配置类,然后Spring会自动扫描到添加了@Configuration的类,并且读取其中的配置信息。而@SpringBootConfiguration是来声明当前类是SpringBoot应用的配置类,项目中只能有一个。所以一般我们无需自己添加。

@EnableAutoConfiguration中的代码:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

    Class<?>[] exclude() default {};

    String[] excludeName() default {};
}

在@EnableAutoConfiguration注解中我们可以看到一个@Import注解,其作用是当前配置文件中引入其他配置类。这里引入了AutoConfigurationImportSelector类,在这个类中有相应的方法用来加载文件中的配置,之后@EnableAutoConfiguration可以帮助SpringBoot应用将所有符合条件的@Configuration配置都加载到当前SpringBoot创建并使用的IOC容器中,进而实现@EnableAutoConfiguration自动配置的功能。

加载的文件:(spring-boot-autoconfigure.jar/META-INF/*)
在这里插入图片描述

SpringBoot内部对大量的第三方库或Spring内部库进行了默认配置,这些配置是否生效,取决于我们是否引入了对应库所需的依赖,如果有那么默认配置就会生效。我们在使用SpringBoot构建项目时,只需要引入所需依赖,配置部分交给了SpringBoot处理。

@ComponentScan中的代码:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
    @AliasFor("basePackages")
    String[] value() default {};

    @AliasFor("value")
    String[] basePackages() default {};

    Class<?>[] basePackageClasses() default {};

    Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;

    Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;

    ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;

    String resourcePattern() default "**/*.class";

    boolean useDefaultFilters() default true;

    ComponentScan.Filter[] includeFilters() default {};

    ComponentScan.Filter[] excludeFilters() default {};

    boolean lazyInit() default false;

    @Retention(RetentionPolicy.RUNTIME)
    @Target({})
    public @interface Filter {
        FilterType type() default FilterType.ANNOTATION;

        @AliasFor("classes")
        Class<?>[] value() default {};

        @AliasFor("value")
        Class<?>[] classes() default {};

        String[] pattern() default {};
    }
}

@ComponentScan注解的作用类似与<context:component-scan>标签,通过basePackageClasses或者basePackages属性来指定要扫描的包。如果没有指定这些属性,那么将从声明这个注解的类所在的包开始,扫描包及子包,而我们的@ComponentScan注解声明的类就是main函数所在的启动类,因此扫描的包是该类所在包及其子包。一般启动类会放在一个比较浅的包目录中。

SpringBoot的配置文件

SpringBoot是基于约定的,其中有许多配置都有默认值,而这些默认配置是可以进行覆盖的,我们可以使用application.properties或者application.yml(application.yaml)进行重新配置。
在这里插入图片描述

SpringBoot默认会从Resources目录下依次加载application.yml文件、application.yaml、application.properties文件,后加载的文件会对前面的文件进行覆盖。

在这里插入图片描述

通过application.properties配置默认端口和访问路径:

#服务器端口号
server.port=8081
#当前web应用的名称
server.servlet.context-path=/demo

application.yml配置文件:

YML文件格式是YAML (YAML Aint Markup Language)编写的文件格式(文件拓展名YML文件的扩展名.yml.yaml),YAML是一种直观的能够被电脑识别的的数据数据序列化格式,并且容易被人类阅读,容易和脚本语言交互的,可以被支持YAML库的不同的编程语言程序导入。YML文件是以数据为核心的,比传统的xml方式更加简洁。

语法格式:key: value,value之前必须有一个空格

yml文件中通过空格来代表属性之间的层级关系,属性前的空格个数不限定,相同缩进代表同一个级别

#普通数据的配置
name: zhangsan

#对象配置
person:
  name: zhangsan
  age: 18
  addr: beijing
#或者:行内对象配置
#person: {name: zhangsan,age: 18, addr: beijing}

#配置数组、集合(普通字符串)
city:
  - beijing
  - tianjin
  - chongqing
  - changhai
#或者:city: [beijing,tianjin,chongqing,shanghai]


#配置数组、集合(对象数据)
student:
  - name: tom
    age: 18
    addr: beijing
  - name: lucy
    age: 17
    addr: tianjin
#或者:student: [{name: tom,age: 18,addr: beijing},{name: luck,age: 17,addr: tianjin}]


#Map配置,与对象配置一样
map:
  key1: value1
  key2: value2

#配置端口
server:
  port: 8082

SpringBoot的属性注入

配置文件与配置类的属性映射方式

使用注解@Value映射,我们可以通过@Value注解将配置文件中的值映射到一个Spring管理的Bean的字段上:

application.yml配置

person:
  name: zhangsan
  age: 18

实体Bean代码如下:

@Controller
public class Test1Controller {

    @Value("${name}")
    private String name;

    @Value("${person.addr}")
    private String addr;

    @RequestMapping("/test1")
    @ResponseBody
    public String test1(){
        //获取配置文件的信息
        return "name:"+name+",addr="+addr;
    }
}

打开浏览器访问,注意路径和端口号:
在这里插入图片描述

使用注解@ConfigurationProperties映射:

通过注解@ConfigurationProperties(prefix="配置文件中的key的前缀")可以将配置文件中的配置自动与实体进行映射

application.yml配置如下:

person:
  name: zhangsan
  age: 18
  addr: beijing

实体Bean代码如下:

@Controller
@ConfigurationProperties(prefix = "person")
public class Test2Controller {

    private String name;
    private Integer age;
    private String addr;

    @RequestMapping("/test2")
    @ResponseBody
    public String test1(){
        //获取配置文件的信息
        return "name:"+name+",age="+age+",addr="+addr;
    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getAddr() {
        return addr;
    }

    public void setAddr(String addr) {
        this.addr = addr;
    }
}

打开浏览器访问,注意路径和端口号:
在这里插入图片描述

注意:使用@ConfigurationProperties方式可以进行配置文件与实体字段的自动映射,但需要字段必须提供set方法才可以,而使用@Value注解修饰的字段不需要提供set方法

案例:配置Druid连接池

在pom.xml中添加相关依赖:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.6</version>
</dependency>

在这里插入图片描述

1. 通过@Value使用jdbc.properties文件进行配置

在resources目录下新建一个jdbc.properties文件,并配置相关信息:

jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/boot?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=520992

新建一个JdbcConfig类实现注入

@Configuration  //声明配置类
@PropertySource("classpath:jdbc.properties")   //指定外部属性文件
public class JdbcConfig {

    @Value("${jdbc.url}")   //实现属性注入
    String url;
    @Value("${jdbc.driverClassName}")
    String driverClassName;
    @Value("${jdbc.username}")
    String username;
    @Value("${jdbc.password}")
    String password;

    @Bean   //声明在方法上,将方法返回值作为Bean容器,代替<bean>标签
    public DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(url);
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }
}

2. 使用@ConfigurationProperties注解进行配置

在resources目录下新建一个application.yml文件,并配置相关信息:

jdbc.driverClassName: com.mysql.cj.jdbc.Driver
jdbc.url: jdbc:mysql://localhost:3306/boot?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8
jdbc.username: root
jdbc.password: 520992

我们新建一个JdbcProperties类,用来实现属性注入

@ConfigurationProperties(prefix = "jdbc")
public class JdbcProperties{
    String url;
    String driverClassName;
    String username;
    String password;
    
    /**
     *  Get、Set
     */

}

实现注入

@Configuration
@EnableConfigurationProperties(JdbcProperties.class)
public class JdbcConfig {

    @Bean
    public DataSource dataSource(JdbcProperties jdbc) {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(jdbc.getUrl());
        dataSource.setDriverClassName(jdbc.getDriverClassName());
        dataSource.setUsername(jdbc.getUsername());
        dataSource.setPassword(jdbc.getPassword());
        return dataSource;
    }
}

3. 更简单的方式进行配置

我们可以直接把@ConfigurationProperties(prefix = "jdbc")声明在需要使用的@Bean的方法上实现注入

@Configuration
public class JdbcConfig {

    // 声明要注入的属性前缀,SpringBoot会检查返回的类是否有对应属性的set方法
    // 如果有,把相关属性通过set方法注入到DataSource中
    @Bean
    @ConfigurationProperties(prefix = "jdbc")
    public DataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        return dataSource;
    }

}

测试代码:使用debug运行

@RestController
public class TestController {

    @Autowired
    private DataSource dataSource;

    @RequestMapping("/test.do")
    public String quick(){
        return "Hello SpringBoot"+dataSource;
    }
}

可以看到已经注入成功
在这里插入图片描述

在这里插入图片描述

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙源lll

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值