springboot敏捷开发 笔记

导读:本篇文章讲解 springboot敏捷开发 笔记,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

SpringBoot


时间安排:
    08:30 -- 09:30  面试题
    09:30 -- 12:00  上课
        
    14:00 -- 15:00  练习
    15:00 -- 17:30  上课
    17:30 -- 18:00  练习
        
    19:00 -- 21:30  晚自习    
    

本章知识点

一 敏捷开发

1.1 什么是敏捷开发


 敏捷开发以用户的需求进化为核心,采用迭代、循序渐进的方法进行软件开发。
 在敏捷开发中,软件项目在构建初期被切分成多个子项目,各个子项目的成果都经过测试,具备可视、可集成和可运行使用的特征。换言之,就是把一个大项目分为多个相互联系,但也可独立运行的小项目,并分别完成,在此过程中软件一直处于可使用状态。[ 其实就是使用 maven工具 构建父子工程 ]
    

1.2 敏捷开发的优势

如果不进行maven父子工程搭建 会有什么问题[一期项目 项目搭建方式 有什么问题 ]:

一、业务耦合性高,体积大,All in One

所有的业务都在一个大工程里面,体积庞大,如果需求变更频繁,无法快速满足新业务快速上线和持续交付。

二、部署麻烦

开发时,一处修改,需要重启整个服务,启动耗时长。
每次局部小改动上线,需要对整个系统重新打包部署,部署周期长。

三、水平扩展性差
    
由于是单体应用,不能做某些局部功能对高并发要求高而单独部署,从而造成服务在某些时段响应特别慢。

四、稳定性差

在某一时段,一个高并发请求会导致整个服务宕机,轻则响应慢,重则停止对外提供服务。给用户造成不可估量的损失。

五、代码维护成本高

业务在不停迭代的同时,源代码也在不停的更新迭代,源代码的作者也是换了一波又一波,造成后来者很难理解和维护这些代码,更为恐怖的是多处地方出现重复的代码。



参考:深入理解SpringBoot(二)——SpringBoot基本概念
https://blog.csdn.net/chengyuhaomei520/article/details/127189723?spm=1001.2014.3001.5506
在这里插入图片描述

1.3 敏捷开发项目拆分方式

横向拆分,即按照不同的业务功能,拆分成不同的微服务,如天气数据采集、数据存储、天气查询等服务,形成独立的业务领域微服务集群[springcloud] 
纵向拆分,即把一个业务功能里的不同模块或组件进行拆分。例如,把公共组件拆分成独立的基础设施,下沉到底层,形成相对独立的基础设施层

在这里插入图片描述

在这里插入图片描述

1.4 项目拆分

1 创建一个 maven 的 quickstrat项目 
2 将当前项目的所文件夹删除 [因为当前项目是一个 父项目不允许有任何的内容]
3 将当前项目 pom文件 类型改成 pom [父工程创建完成]
<?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>

  <groupId>com.aaa.haha</groupId>
  <artifactId>demo01</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>


</project>
4 创建子项目 
    
  选中父项目--右键--new--- module 创建子项目
  haha-admin  [web项目]   
  haha-system [java项目]
  haha-common [java项目]
  
  此时父子项目创建完成 
    A 在子项目的pom文件中 会有一个 parent标签 表明当前项目是哪个项目的子项目
        
<parent>
        <artifactId>demo01</artifactId>
        <groupId>com.aaa.haha</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
   B 在父项目中 会有一个  module 标签 表明当前有哪些子项目
 <modules>
    <module>haha-admin</module>
    <module>haha-system</module>
    <module>haha-common</module>
  </modules>
5 建立依赖关系
  haha-admin  [web项目]Controller控制层代码
  haha-system [java项目]  : service 业务层代码 mapper 持久层代码
  haha-common [java项目]  : 工具类等内容 
    
  按照三层架构的思想 controller调用 service  代码 此时父子工程搭建完成之后  无法调用的
  所以我们需要建立项目之前的依赖
    
<?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">
    <parent>
        <artifactId>demo01</artifactId>
        <groupId>com.aaa.haha</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>
    <artifactId>haha-admin</artifactId>
    <packaging>war</packaging>

    <dependencies>

        <dependency>
            <groupId>com.aaa.haha</groupId>
            <artifactId>haha-system</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>


    </dependencies>


</project>
6 导入jar包
 方式1 :在总pom中导入  这样 所有的项目都可以使用   
        我们不采用这种方式 例如 我们总pom中 导入 lombok 这样 所有的子项目都可以使用 
        但是   haha-admin  里面写controller的 根本用不到lombok
    
方式2  :哪个项目需要用什么jar包 哪个项目进行导入
    
  haha-admin  [web项目]   :  springmvc
  haha-system [java项目]  :  mysql-java-connection  mybatis  spring 
  haha-common [java项目]  :  hutool lombok spring 
    
此时要注意  jar包会传递  所以我们需要阻断传递

 <!-- spring-boot-devtools -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional> <!-- 表示依赖不会传递 -->
        </dependency>


<dependencies>

        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
            <scope>provided</scope>
        </dependency>

    </dependencies>
核心思想:
    1 专职专项  哪个地方需要什么 则在哪导入
    2 如果jar包 只有当前工程使用 则阻断传递
    3 jar包多个工程都需要用到 在最基层导入
7 版本控制
  jar包导入完成之后  如果需要升级版本  只需要改依赖坐标的 <version></version> 就可以了 
  但是 现在jar包分散在不同的项目中  所以我们如果项目体量太大 很难找到jar包的所在位置
  所以我们需要进行版本控制:
    在父项目中  :
      
<?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>



  <groupId>com.aaa.haha</groupId>
  <artifactId>demo01</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>

  <modules>
    <module>haha-admin</module>
    <module>haha-system</module>
    <module>haha-common</module>
  </modules>

  <properties>
     <lombok.version>1.18.22</lombok.version>
  </properties>

  <dependencyManagement>
       <dependencies>
         <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
         <dependency>
           <groupId>org.projectlombok</groupId>
           <artifactId>lombok</artifactId>
           <version>${lombok.version}</version>
           <scope>provided</scope>
         </dependency>
       </dependencies>
  </dependencyManagement>

</project>



在子项目中:
<?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">
    <parent>
        <artifactId>demo01</artifactId>
        <groupId>com.aaa.haha</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>haha-common</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

</project>

在父项目中 使用 <dependencyManagement> 管理所有的jar包 这个标签的作用是 代表当前项目中 引入哪些依赖 但是并不传递给子项目  此时子项目 如果用到 <dependencyManagement> 中管理的依赖 此时只需要导入 不需要填写版本号。这样做 依然遵循 子项目导入jar包各取所需 ,并且修改版本的时候 只需要在父pom中修改即可
    

1.5 boot的由来

我们之前的开发都是使用ssm框架。如果需要搭建一个项目,则ssm整合。大家试想一下,ssm整合其实是一个机械性操作。
所以spring就发现了这个问题,所以他们就要提出解决方案。如果再需要进行ssm整合,则不需要那么麻烦。
spring帮我们创建了一个父项目。在父项目中将spring的产品 以及其他第三方框架进行整合 ,程序要再去开发的时候 ,只需要继承spring整合好的父项目。然后进行开发。让程序员只专注于开发。
    
spring将这个父项目 命名为  springboot 。
也就是说 我们玩springboot  技术上还是以前的那一些,只不过不需要自己去整合了。

​     Spring  Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot 致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。

​     SpringBoot是由Pivotal团队在2013年开始研发、20144月发布第一个版本的全新开源的轻量级框架。它基于Spring4.0设计,不仅继承了Spring框架原有的优秀特性,而且还通过简化配置来进一步简化了Spring应用的整个搭建和开发过程。另外SpringBoot通过集成大量的框架使得依赖包的版本冲突,以及引用的不稳定性等问题得到了很好的解决。

SpringBoot所具备的特征有:

(1)可以创建独立的[Spring]应用程序,并且基于其MavenGradle插件,可以创建可执行的JARsWARs;

(2)内嵌TomcatJettyServlet容器;

(3)提供自动配置的“starter”项目对象模型(POMS)以简化[Maven]配置;

(4)尽可能自动配置Spring容器;约定大于配置

(5)提供准备好的特性,如指标、健康检查和外部化配置;

(6)绝对没有代码生成,不需要XML配置。 

二 boot项目入门

2.1 boot项目搭建


1 创建项目
2 在总pom中 添加依赖  [我们当前项目要作为 boot的子项目 所以 要将boot 添加成 parent ]

 <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.5.1</version>
  </parent> 
3 添加依赖 在common中添加依赖
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
总pom:
<?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>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.5.1</version>
  </parent>


  <groupId>com.aaa.haha</groupId>
  <artifactId>demo01</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>



  <modules>
    <module>haha-admin</module>
    <module>haha-system</module>
    <module>haha-common</module>
  </modules>

  <properties>

  </properties>

  <dependencyManagement>
       <dependencies>
         

       </dependencies>
  </dependencyManagement>

</project>

4 在admin中创建一个 启动类   启动类的位置!!!
package com.aaa.haha;

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

@SpringBootApplication
public class App {

    public static void main(String[] args) {
        SpringApplication.run(App.class,args);
    }
}
5 创建一个 controller测试
package com.aaa.haha.controller;


import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("haha")
public class HahaController {


    @RequestMapping("hehe")
    public String   test(){
        return  "hello  boot";
    }

}
6 运行测试 启动类的main函数 运行

2.2 boot依赖和starter的理解


在boot项目中  引入的第三方都是 starter 
 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

该如何理解stater呢?

我们从maven的pom中开始看起:
在我们的总pom中 将当前项目作为 springboot的子项目 
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.5.1</version>
  </parent>
点进去 查看这个pom  这个项目 主要是插件管理 其也是一个子项目  再看他的父项目
 <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.5.1</version>
  </parent>
  <artifactId>spring-boot-starter-parent</artifactId>
  <packaging>pom</packaging>
  <name>spring-boot-starter-parent</name>

再点进去  这个项目是根项目  用来整合框架的
<modelVersion>4.0.0</modelVersion>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-dependencies</artifactId>
  <version>2.5.1</version>
  <packaging>pom</packaging>
  <name>spring-boot-dependencies</name>
我们在这个pom中发现 <dependencyManagement> 原来 boot就是一个父项目 
 整合了200框架 我们需要什么就到什么即可
    
 而 200框架 很多都是联用的  我们ssm整合的时候 需要什么就导入什么  在boot中简化了
 类似于 肯德基套餐的效果 
    夏日缤纷套餐: 鸡腿堡  可乐 薯条  哈哈
    校园优惠套餐: 鸡腿堡  雪碧 薯条 鸡柳  哈哈 
 而 springboot 中的 starter 就是套餐的思想 我们发现 我们仅仅导入一个依赖   
 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    此时 spring springmvc  jackson 等内容全有了 

2.3 配置文件

boot配置文件有两种类型:  properties 和 yml 
    
一般我们都是放到  admin项目下的 resources 中的 config 
以前我们使用spring springmvc的时候 配置文件的类型是 xml格式
在springboot中 配置文件有两种类型:  properties    yml 

此时我们创建  application.properties
此时我们创建  application.yml

这是springboot的约定大于配置
1 约定从哪里来的
  <resources>
      <resource>
        <directory>${basedir}/src/main/resources</directory>
        <filtering>true</filtering>
        <includes>
          <include>**/application*.yml</include>
          <include>**/application*.yaml</include>
          <include>**/application*.properties</include>
        </includes>
      </resource>
      <resource>
        <directory>${basedir}/src/main/resources</directory>
        <excludes>
          <exclude>**/application*.yml</exclude>
          <exclude>**/application*.yaml</exclude>
          <exclude>**/application*.properties</exclude>
        </excludes>
      </resource>
      
 2 配置项是如何被读取并执行内容
   当我们配置到配置文件中的内容,boot会有一个配置类去读取配置文件的内容
      
@ConfigurationProperties(
    prefix = "server",
    ignoreUnknownFields = true
)
public class ServerProperties {
    private Integer port;
    private InetAddress address;


实际开发中 ,git的分支其实就有很多环境线上:prod(正式)、stageing(预发)线下:test(公共测试环境)、dev(研发自用环境)
boot中也是有不同环境的配置文件的 ,不同的配置文件在不同的场景中进行使用
此时我们创建不同环境得配置文件
    application-dev.properties
    application-test.properties
    application-pro.properties
    
每个配置文件用来配置不同环境中的信息
在总配置文件中application.properties 选取使用哪一种配置环境
    
spring.profiles.active=dev
    
这是环境配置文件选取的一种方式 ,还可以通过maven进行选取[maven添加插件] ,还可以启动类配置  


2.4 boot启动流程【面试题 自己整理】

我们启动springboot项目 其实就是在main函数中 执行了一句代码
SpringApplication.run(App.class,args);

此时boot就启动了 他是如何启动的呢? 核心操作就在这个 run函数中 
 run(添加SpringBootApplication注解的字节码  , main函数的参数  )   
    
main函数的参数 是用来配置 启动信息的      我们java代码执行的时候 javac java 命令  
添加SpringBootApplication注解的字节码  用来自动配置的(约定)
我们查看一下run的源代码
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
		return run(new Class<?>[] { primarySource }, args);
}
此时我们再看这个run
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
		return new SpringApplication(primarySources).run(args);
}
这个run中干了两件事情 1 new SpringApplication(primarySources)
                   2 用这个对象调用 run函数
    
A 创建这个对象    new SpringApplication(primarySources) 做了这些事情
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
		this.resourceLoader = resourceLoader;
        // 断言 测试用到的 
		Assert.notNull(primarySources, "PrimarySources must not be null");
		this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
		this.webApplicationType = WebApplicationType.deduceFromClasspath();
		this.bootstrapRegistryInitializers = getBootstrapRegistryInitializersFromSpringFactories();
		setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
		this.mainApplicationClass = deduceMainApplicationClass();
	}

B 对象调用run
    public ConfigurableApplicationContext run(String... args) {
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		DefaultBootstrapContext bootstrapContext = createBootstrapContext();
		ConfigurableApplicationContext context = null;
		configureHeadlessProperty();
		SpringApplicationRunListeners listeners = getRunListeners(args);
		listeners.starting(bootstrapContext, this.mainApplicationClass);
		try {
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
			ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
			configureIgnoreBeanInfo(environment);
			Banner printedBanner = printBanner(environment);
			context = createApplicationContext();
			context.setApplicationStartup(this.applicationStartup);
			prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
			refreshContext(context);
			afterRefresh(context, applicationArguments);
			stopWatch.stop();
			if (this.logStartupInfo) {
				new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
			}
			listeners.started(context);
			callRunners(context, applicationArguments);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, listeners);
			throw new IllegalStateException(ex);
		}

		try {
			listeners.running(context);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, null);
			throw new IllegalStateException(ex);
		}
		return context;
	}

2.5 boot自动装配原理

 SSM的时候 配置整合MyBatis 是如何实现的? 
     我们需要手动将 mybatis 配置成 spring的 bean 交给spring管理

    <!-- 属性文件加载  我们现在要使用 druid的数据库连接池
         druid的数据库连接池有一个配置文件  druid.properties 里面都是druid的配置信息
         此时在spring的配置文件中 需要去读druid.properties中的信息
         在spring 中可以配置PropertyPlaceholderConfigurer 这样的bean
         这个bean 就会根据location 配置的地址classpath:druid.properties
         去读取配置信息
     -->
    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:druid.properties"></property>
    </bean>

    <!-- 我们当前项目 使用的数据库连接池是 阿里巴巴的 druid
         数据库连接池的使用  创建数据库连接池对象 ,需要连接对象conn的时候  从连接池对象中获取
         此时我们使用spring  创建连接池对象的工作就交给spring
         配置当前bean  classcom.alibaba.druid.pool.DruidDataSource
         此时spring就会管理数据库连接池对象的创建
     -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" >
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url"             value="${jdbc.url}"/>
        <property name="username"        value="${jdbc.username}"/>
        <property name="password"        value="${jdbc.password}"/>
    </bean>



    <!--  spring整合 mybatis SqlSessionFactoryBean -->
    <bean id="sqlFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 使用哪个数据库连接池  此时使用 ref引用 dataSource 代表使用的是 上面的 druid数据库连接池  -->
        <property name="dataSource" ref="dataSource" />
        <!-- 配置 mybatis的 配置文件位置-->
        <property name="configLocation" value="classpath:mybatis-config.xml" />
        <!-- 扫描 所有的  mapper.xml文件的位置 注意 此处容易出问题  -->
        <property name="mapperLocations" value="classpath:mapper/*Mapper.xml"></property>
        <!--别名扫描-->
        <property name="typeAliasesPackage"  value="com.aaa.pojo"></property>
    </bean>


    <!-- mapper 扫描接口  -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--  mapper对应的接口的包名  -->
        <property name="basePackage" value="com.aaa.mapper" />
        <!--  扫描接口的时候 要知道为谁扫描的-->
        <property name="sqlSessionFactoryBeanName" value="sqlFactory" />
    </bean>

但是springboot 不需要这么麻烦  只需要导包 然后再properties配置即可




boot 约定大于配置 。我们在ssm中都需要配置包扫描等等的内容 但是在boot中不需要配置 因为默认的约定是添加 @SpringBootApplication注解类的下级 全部被扫描 这个注解是一个复合注解

@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 {};


	@AliasFor(annotation = ComponentScan.class, attribute = "nameGenerator")
	Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;

	@AliasFor(annotation = Configuration.class)
	boolean proxyBeanMethods() default true;

}

所以我们查看@EnableAutoConfiguration  自动装配使用的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class) 
public @interface EnableAutoConfiguration {
    
告诉我们自动装配的类是:AutoConfigurationImportSelector
    这个类中有一个方法
    protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
		List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
				getBeanClassLoader());// 自动装配加载第三方的类 
		Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
				+ "are using a custom packaging, make sure that file is correct.");
		return configurations;
	}
 而这个loadFactoryNames 会调用 loadSpringFactories  去读取配置信息   
    
  	public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
		ClassLoader classLoaderToUse = classLoader;
		if (classLoaderToUse == null) {
			classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
		}
		String factoryTypeName = factoryType.getName();
		return loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList());
	}
    
    
在这个方法中 classLoader.getResources(FACTORIES_RESOURCE_LOCATION);   就是加载配置类信息
	private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader) {
		Map<String, List<String>> result = cache.get(classLoader);
		if (result != null) {
			return result;
		}

		result = new HashMap<>();
		try {
			Enumeration<URL> urls = classLoader.getResources(FACTORIES_RESOURCE_LOCATION);  
       这个字符常量FACTORIES_RESOURCE_LOCATION 就是
 public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
此时springboot 就会去找这个文件   而这个文件里面标明了 当前第三方框架 自动装配的类 是哪个
 # Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.mybatis.spring.boot.autoconfigure.MybatisLanguageDriverAutoConfiguration,\
org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration
    
所以 boot 就回去 自动加载这两个类 【约定第三方会将自己的配置类 类名写到 META-INF/spring.factories 文件中 】而在这个自动装配的类中 会读取 配置文件的信息 并且注入

在这里插入图片描述

三 SpringBoot整合 mybatis

3.1 整合

1 总pom中添加依赖
<?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>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.5.1</version>
  </parent>


  <groupId>com.aaa.haha</groupId>
  <artifactId>demo01</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>


  <modules>
    <module>haha-admin</module>
    <module>haha-system</module>
    <module>haha-common</module>
  </modules>

  <properties>
    <mybatis.version>2.2.2</mybatis.version>
    <mysql.version>5.1.47</mysql.version>
    <druid.version>1.2.6</druid.version>
  </properties>

  <dependencyManagement>
       <dependencies>
         <dependency>
           <groupId>org.mybatis.spring.boot</groupId>
           <artifactId>mybatis-spring-boot-starter</artifactId>
           <version>${mybatis.version}</version>
         </dependency>

         <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
           <version>${mysql.version}</version>
         </dependency>

         <dependency>
           <groupId>com.alibaba</groupId>
           <artifactId>druid-spring-boot-starter</artifactId>
           <version>${druid.version}</version>
         </dependency>

       </dependencies>
  </dependencyManagement>

</project>

2 在需要使用的地方 引入 system中引入
<?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">
    <parent>
        <artifactId>demo01</artifactId>
        <groupId>com.aaa.haha</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>haha-system</artifactId>

    <dependencies>

        <dependency>
            <groupId>com.aaa.haha</groupId>
            <artifactId>haha-common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>


        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
        </dependency>

    </dependencies>
</project>
3 在配置文件中配置 信息

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

mybatis.type-aliases-package=com.aaa.boot.pojo
mybatis.mapper-locations=classpath:mapper/*.xml

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/118006.html

(0)
seven_的头像seven_bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!