SpringBoot

95 阅读7分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第29天

SpringBoot笔记

1.第一个SpringBoot程序

1.1环境配置

我们将学习如何快速的创建一个Spring Boot应用,并且实现一个简单的Http请求处理。通过这个例子对Spring Boot有一个初步的了解,并体验其结构简单、开发快速的特性。

我的环境准备:

  • java version “1.8.0_181”
  • Maven-3.6.1
  • SpringBoot 2.x 最新版

开发工具:

  • IDEA

1.2创建基础项目说明

Spring官方提供了非常方便的工具让我们快速构建应用,IDEA也集成了这个网站

Spring Initializr:start.spring.io/

1.3.1项目创建方式一

使用Spring Initializr 的 Web页面创建项目

①打开 start.spring.io/

②填写项目信息

③点击”Generate Project“按钮生成项目;下载此项目

④解压项目包,并用IDEA以Maven项目导入,一路下一步即可,直到项目导入完毕。

⑤如果是第一次使用,可能速度会比较慢,包比较多、需要耐心等待一切就绪。

1.3.2项目创建方式二

使用 IDEA 直接创建项目

①创建一个新项目

②选择spring initalizr , 可以看到默认就是去官网的快速构建工具那里实现(建议改成阿里的镜像,快很多:start.aliyun.com

③填写项目信息

④选择初始化的组件(初学勾选 Web 即可)

⑤填写项目路径

⑥等待项目构建成功

1.3.3项目结构分析:

通过上面步骤完成了基础项目的创建。就会自动生成以下文件。

1、程序的主启动类(程序的主入口)

2、一个 application.properties 配置文件(SpringBoot的核心配置文件)

3、一个 测试类

4、一个 pom.xml

pom.xml文件分析: 打开pom.xml,看看Spring Boot项目的依赖:

 <!-- 父依赖 -->
 <parent>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-parent</artifactId>
     <version>2.2.5.RELEASE</version>
     <relativePath/>
 </parent>
 ​
 <dependencies>
     <!-- web场景启动器 -->
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
     </dependency>
     <!-- springboot单元测试 -->
     <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>
 ​

编写一个http接口

①在主程序的同级目录下,新建一个controller包,一定要在同级目录下,否则识别不到 ②在包中新建一个HelloController类

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

③编写完毕后,从主程序启动项目,浏览器发起请求,看页面返回;控制台输出了 Tomcat 访问的端口号!

image-20221027091202830

更改端口号:在application资源文件中配置

  server.port = xxxx

1.3SpringBoot特点

1.3.1依赖管理

  • 父项目做依赖管理
 依赖管理    
 <parent>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-parent</artifactId>
         <version>2.3.4.RELEASE</version>
 </parent>
 ​
 他的父项目
  <parent>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-dependencies</artifactId>
     <version>2.3.4.RELEASE</version>
   </parent>
 ​
 几乎声明了所有开发中常用的依赖的版本号,自动版本仲裁机制
 ​
  • 开发导入starter场景启动器
 1、见到很多 spring-boot-starter-* : *就某种场景
 2、只要引入starter,这个场景的所有常规需要的依赖我们都自动引入
 3、SpringBoot所有支持的场景
 https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-starter
 4、见到的  *-spring-boot-starter: 第三方为我们提供的简化开发的场景启动器。
 5、所有场景启动器最底层的依赖
 <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter</artifactId>
   <version>2.3.4.RELEASE</version>
   <scope>compile</scope>
 </dependency>
 ​
  • 无需关注版本号,自动版本仲裁
 1、引入依赖默认都可以不写版本
 2、引入非版本仲裁的jar,要写版本号。
 ​
  • 可以修改默认版本号
 1、查看spring-boot-dependencies里面规定当前依赖的版本 用的 key。
 2、在当前项目里面重写配置
     <properties>
         <mysql.version>5.1.43</mysql.version>
     </properties>
 ​

1.3.2自动配置

  • 自动配好Tomcat

    • 引入Tomcat依赖。
    • 配置Tomcat
  <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <version>2.3.4.RELEASE</version>
        <scope>compile</scope>
      </dependency>
 ​

自动配好SpringMVC

  • 引入SpringMVC全套组件
  • 自动配好SpringMVC常用组件(功能)
  • 自动配好Web常见功能,如:字符编码问题
  • SpringBoot帮我们配置好了所有web开发的常见场景
  • 默认的包结构
  • 主程序所在包及其下面的所有子包里面的组件都会被默认扫描进来
  • 无需以前的包扫描配置
  • 想要改变扫描路径,@SpringBootApplication(scanBasePackages=“com.guo”)

或者@ComponentScan 指定扫描路径

  • @SpringBootAppliction注解
  @SpringBootApplication
  等同于
  @SpringBootConfiguration
  @EnableAutoConfiguration
  @ComponentScan("com.guo.boot")
 ​
  • 各种配置拥有默认值

    • 默认配置最终都是映射到某个类上,如:MultipartProperties

    • 配置文件的值最终会绑定每个类上,这个类会在容器中创建对象

    • 按需加载所有自动配置项

      • 非常多的starter
      • 引入了哪些场景这个场景的自动配置才会开启
      • SpringBoot所有的自动配置功能都在 spring-boot-autoconfigure 包里面

1.4容器功能

1.4.1组件添加

1.@Configuration 给类添加这个注解后相当于原来的向bean注入的bean.xml文件

  • 基本使用

    • Full模式(全配置)和Lite模式(轻量级配置)

代码示例:

 #############################Configuration使用示例######################################################
 /**
  * 1、配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实例的
  * 2、配置类本身也是组件
  * 3、proxyBeanMethods:代理bean的方法
  *      Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
  *      Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】
  *      组件依赖必须使用Full模式默认,proxyBeanMethods = true。
         其他默认是否Lite模式:proxyBeanMethods = flase
  *
  *
  *
  */
 @Configuration(proxyBeanMethods = true) //告诉SpringBoot这是一个配置类 == 配置文件
 public class MyConfig {
 ​
     /**
      * Full:外部无论对配置类中的这个组件注册方法调用多少次获取的都是之前注册容器中的单实例对象
      * @return
      */
     @Bean //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
     public User user01(){
         User zhangsan = new User("zhangsan", 18);
         //user组件依赖了Pet组件
         zhangsan.setPet(tomcatPet());
         return zhangsan;
     }
 ​
     @Bean("tom")
     public Pet tomcatPet(){
         return new Pet("tomcat");
     }
 }
 ​
 ​
 ################################@Configuration测试代码如下########################################
 @SpringBootConfiguration
 @EnableAutoConfiguration
 @ComponentScan("com.atguigu.boot")
 public class MainApplication {
 ​
     public static void main(String[] args) {
         //1、返回我们IOC容器
         ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
 ​
         //2、查看容器里面的组件
         String[] names = run.getBeanDefinitionNames();
         for (String name : names) {
             System.out.println(name);
         }
 ​
         //3、从容器中获取组件
 ​
         Pet tom01 = run.getBean("tom", Pet.class);
 ​
         Pet tom02 = run.getBean("tom", Pet.class);
 ​
         System.out.println("组件:"+(tom01 == tom02));
 ​
 ​
         //4、com.atguigu.boot.config.MyConfig$$EnhancerBySpringCGLIB$$51f1e1ca@1654a892
         MyConfig bean = run.getBean(MyConfig.class);
         System.out.println(bean);
 ​
         //如果@Configuration(proxyBeanMethods = true)代理对象调用方法。SpringBoot总会检查这个组件是否在容器中有。
         //保持组件单实例
         User user = bean.user01();
         User user1 = bean.user01();
         System.out.println(user == user1);
 ​
 ​
         User user01 = run.getBean("user01", User.class);
         Pet tom = run.getBean("tom", Pet.class);
 ​
         System.out.println("用户的宠物:"+(user01.getPet() == tom));
 ​
     }
 }
 ​

2、@Bean、@Component、@Controller、@Service、@Repository

3、@ComponentScan、@Import @Import会给容器中自动创建这两个类型的组件

  * 4@Import({User.class, DBHelper.class})
  *      给容器中自动创建出这两个类型的组件、默认组件的名字就是全类名
  */
 ​
 @Import({User.class, DBHelper.class})
 @Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件
 public class MyConfig {
 }
 ​

4.@Conditional(条件装配注解)

条件装配:当满足Conditional指定的条件,则进行组件注入

image-20221027170953154

先看结论:当这个注解配置在类上时,只有这个类内注入了响应名称的组件才会生成相应的实体,

当配置在部分方法时,只有相应的被注入才可以生成实体,否则就不生效

 =====================测试条件装配==========================
 @Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件
 //@ConditionalOnBean(name = "tom")
 @ConditionalOnMissingBean(name = "tom")
 public class MyConfig {
 ​
     /**
      * Full:外部无论对配置类中的这个组件注册方法调用多少次获取的都是之前注册容器中的单实例对象
      * @return
      */
 ​
     @Bean //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
     public User user01(){
         User zhangsan = new User("zhangsan", 18);
         //user组件依赖了Pet组件
         zhangsan.setPet(tomcatPet());
         return zhangsan;
     }
 ​
     @Bean("tom22")
     public Pet tomcatPet(){
         return new Pet("tomcat");
     }
 }
 ​
 public static void main(String[] args) {
         //1、返回我们IOC容器
         ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
 ​
         //2、查看容器里面的组件
         String[] names = run.getBeanDefinitionNames();
         for (String name : names) {
             System.out.println(name);
         }
 ​
         boolean tom = run.containsBean("tom");
         System.out.println("容器中Tom组件:"+tom);
 ​
         boolean user01 = run.containsBean("user01");
         System.out.println("容器中user01组件:"+user01);
 ​
         boolean tom22 = run.containsBean("tom22");
         System.out.println("容器中tom22组件:"+tom22);
 ​
 ​
     }
 ​

1.4.2原生配置文件引入

@ImportResource

 ======================beans.xml=========================
 <?xml version="1.0" encoding="UTF-8"?>
 <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
 ​
     <bean id="haha" class="com.atguigu.boot.bean.User">
         <property name="name" value="zhangsan"></property>
         <property name="age" value="18"></property>
     </bean>
 ​
     <bean id="hehe" class="com.atguigu.boot.bean.Pet">
         <property name="name" value="tomcat"></property>
     </bean>
 </beans>
 ​

1.4.3配置绑定

如何使用Java读取到properties文件中的内容,并且把它封装到JavaBean中,以供随时使用;

 public class getProperties {
      public static void main(String[] args) throws FileNotFoundException, IOException {
          Properties pps = new Properties();
          pps.load(new FileInputStream("a.properties"));
          Enumeration enum1 = pps.propertyNames();//得到配置文件的名字
          while(enum1.hasMoreElements()) {
              String strKey = (String) enum1.nextElement();
              String strValue = pps.getProperty(strKey);
              System.out.println(strKey + "=" + strValue);
              //封装到JavaBean。
          }
      }
  }
 ​

1.@ConfigurationProperties 注意想要使用这个注解必须声明组件注解@Component

 /**
  * 只有在容器中的组件,才会拥有SpringBoot提供的强大功能
  */
 @Component
 @ConfigurationProperties(prefix = "mycar")
 public class Car {
 ​
     private String brand;
     private Integer price;
 ​
     public String getBrand() {
         return brand;
     }
 ​
     public void setBrand(String brand) {
         this.brand = brand;
     }
 ​
     public Integer getPrice() {
         return price;
     }
 ​
     public void setPrice(Integer price) {
         this.price = price;
     }
 ​
     @Override
     public String toString() {
         return "Car{" +
                 "brand='" + brand + ''' +
                 ", price=" + price +
                 '}';
     }
 }
 ​

对应的application.property文件:

 mycar.price = 100000
 mycar.brand = BYD
 ​

@Component + @ConfigurationProperties

 @EnableConfigurationProperties(Car.class)
 //1、开启Car配置绑定功能
 //2、把这个Car这个组件自动注册到容器中
 public class MyConfig {
 }
 ​