欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot中的自動(dòng)裝配原理詳解

 更新時(shí)間:2024年11月07日 08:20:08   作者:懶惰蝸牛  
本文將通過在Spring中集成MyBatis和在SpringBoot中集成MyBatis為大家簡(jiǎn)單梳理自動(dòng)配置過程,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

前言

通過兩個(gè)簡(jiǎn)單的案例:在Spring中集成MyBatis、在SpringBoot中集成MyBatis

找出兩者的差異,初探Spring發(fā)展到SpringBoot的部分演化過程

以MyBatis為例,簡(jiǎn)單梳理自動(dòng)配置過程

一、Spring整合MyBatis

1.1pom文件

pom.xml

 <!-- Spring JDBC -->
 <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-jdbc</artifactId>
     <version>${spring.version}</version>
 </dependency>
 ?
 <!-- MyBatis核心包 -->
 <dependency>
     <groupId>org.mybatis</groupId>
     <artifactId>mybatis</artifactId>
     <version>3.5.10</version>
 </dependency>
 ?
 <!-- MyBatis-Spring 整合包 -->
 <dependency>
     <groupId>org.mybatis</groupId>
     <artifactId>mybatis-spring</artifactId>
     <version>2.0.6</version>
 </dependency>
 ?
 <!-- Druid數(shù)據(jù)庫連接池 -->
 <dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>druid</artifactId>
     <version>1.1.23</version>
 </dependency>
 ?
 <!-- MySQL數(shù)據(jù)庫驅(qū)動(dòng) -->
 <dependency>
     <groupId>mysql</groupId>
     <artifactId>mysql-connector-java</artifactId>
     <version>8.0.26</version>
 </dependency>

1.2配置類

MyBatisConfig

 package com.lazy.snail;
 ?
 import com.alibaba.druid.pool.DruidDataSource;
 import org.apache.ibatis.session.SqlSessionFactory;
 import org.mybatis.spring.SqlSessionFactoryBean;
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.PropertySource;
 ?
 import javax.sql.DataSource;
 ?
 /**
  * @ClassName MyBatisConfig
  * @Description TODO
  * @Author lazysnail
  * @Date 2024/11/5 16:20
  * @Version 1.0
  */
 @Configuration
 @PropertySource("classpath:db.properties")
 @MapperScan("com.lazy.snail.mapper")
 public class MyBatisConfig {
     @Value("${jdbc.url}")
     private String url;
 ?
     @Value("${jdbc.username}")
     private String username;
 ?
     @Value("${jdbc.password}")
     private String password;
 ?
     @Value("${jdbc.driverClassName}")
     private String driverClassName;
 ?
     @Bean
     public DataSource dataSource() {
         DruidDataSource dataSource = new DruidDataSource();
         // 基本配置
         dataSource.setDriverClassName(driverClassName);
         dataSource.setUrl(url);
         dataSource.setUsername(username);
         dataSource.setPassword(password);
 ?
         // Druid 高級(jí)配置
 ?
         return dataSource;
     }
 ?
     @Bean
     public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
         SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
         factoryBean.setDataSource(dataSource);
         return factoryBean.getObject();
     }
 }

1.3數(shù)據(jù)源屬性配置文件

 # db.properties
 jdbc.url=jdbc:mysql://*.*.*.*:3306/snail_db
 jdbc.username=username
 jdbc.password=password
 jdbc.driverClassName=com.mysql.cj.jdbc.Driver

1.4mapper

UserMapper

 package com.lazy.snail.mapper;
 ?
 import com.lazy.snail.domain.User;
 import org.apache.ibatis.annotations.Insert;
 import org.springframework.stereotype.Repository;
 ?
 /**
  * @ClassName UserMapper
  * @Description TODO
  * @Author lazysnail
  * @Date 2024/11/5 16:27
  * @Version 1.0
  */
 @Repository
 public interface UserMapper {
     @Insert("insert into user_info(user_id, name, email) values(#{userId}, #{name}, #{email})")
     void insert(User user);
 }

1.5測(cè)試類

SpringTest

 package com.lazy.snail;
 ?
 import com.lazy.snail.domain.User;
 import com.lazy.snail.service.UserService;
 import lombok.extern.slf4j.Slf4j;
 import org.junit.jupiter.api.Test;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ConfigurableApplicationContext;
 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 ?
 @Slf4j
 public class SpringTest {
 ?
     @Test
     void test() {
         ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
         UserService userService = context.getBean(UserService.class);
         userService.createUser(new User(1, "lazysnail", "lazy_snail@aliyun.com"));
     }
 }

二、SpringBoot整合MyBatis

2.1pom文件

pom.xml

 <!-- springboot集成mybatis 自動(dòng)為mybatis創(chuàng)建和配置所需的bean,簡(jiǎn)化mybatis的使用 -->
 <dependency>
     <groupId>org.mybatis.spring.boot</groupId>
     <artifactId>mybatis-spring-boot-starter</artifactId>
     <version>2.2.2</version>
 </dependency>
 ?
 <!-- 數(shù)據(jù)庫連接池 -->
 <dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>druid-spring-boot-starter</artifactId>
     <version>1.2.8</version>
 </dependency>
 ?
 <!-- 數(shù)據(jù)庫驅(qū)動(dòng) -->
 <dependency>
     <groupId>mysql</groupId>
     <artifactId>mysql-connector-java</artifactId>
     <version>8.0.33</version>
 </dependency>

2.2配置文件

application.yml

 spring:
   datasource:
     druid:
       url: jdbc:mysql://*.*.*.*:3306/snail_db
       username: username
       password: password
       driver-class-name: com.mysql.cj.jdbc.Driver

2.3mapper

UserMapper

 package com.lazy.snail.mapper;
 ?
 import com.lazy.snail.domain.User;
 import org.apache.ibatis.annotations.Insert;
 import org.apache.ibatis.annotations.Mapper;
 ?
 /**
  * @ClassName UserMapper
  * @Description TODO
  * @Author lazysnail
  * @Date 2024/10/10 14:03
  * @Version 1.0
  */
 @Mapper
 public interface UserMapper {
     @Insert("insert into user_info(user_id, name, email) values(#{userId}, #{name}, #{email})")
     void insert(User user);
 }

2.4測(cè)試類

ApplicationTests

package com.lazy.snail;

import com.lazy.snail.domain.User;
import com.lazy.snail.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class ApplicationTests {

    @Autowired
    private UserService userService;

    @Test
    void contextLoads() {
        User user = new User();
        user.setUserId(4);
        userService.createUser(user);
    }
}

三、Spring與SpringBoot整合MyBatis區(qū)別

3.1pom文件差異

  • Spring中單獨(dú)引入功能模塊的依賴,如mybatis、mybatis-spring
  • SpringBoot中引入starter概念,需要整合mybatis,只需要引入mybatis-spring-boot-starter依賴

Starter POMs are a set of convenient dependency descriptors that you can include in your application. You get a one-stop-shop for all the Spring and related technology that you need, without having to hunt through sample code and copy paste loads of dependency descriptors. For example, if you want to get started using Spring and JPA for database access, just include the spring-boot-starter-data-jpa dependency in your project, and you are good to go.

通過引入 Starter,無需手動(dòng)查找和復(fù)制大量依賴,避免了我們?nèi)ヒ胍蕾囁鶐淼穆闊?/p>

3.2配置類及配置文件差異

Spring中我們需要自定義MyBatis的配置類,專門管理DataSource、SqlSessionFactory、MapperScannerConfigurer這些組件

SpringBoot集成MyBatis時(shí)沒有任何的相關(guān)配置類(基礎(chǔ)版),因?yàn)镾pringBoot提供了自動(dòng)配置功能,MyBatis 的大部分配置可以通過 mybatis-spring-boot-starter 自動(dòng)完成,只需要引入相關(guān)的依賴,并在 application.propertiesapplication.yml 中進(jìn)行一些簡(jiǎn)單配置即可,Spring Boot 會(huì)自動(dòng)創(chuàng)建并配置所需的 Bean(如 SqlSessionFactory、MapperScannerConfigurer 等)。

四、SpringBoot怎么自動(dòng)配置MyBatis

4.1MyBatis自動(dòng)配置信息位置

4.2讀取自動(dòng)配置信息

4.3解析bean定義信息

4.3.1解析Application中@Import

/**
 * 激活Spring應(yīng)用上下問的自動(dòng)配置功能,嘗試猜測(cè)和配置需要的bean。
 * 自動(dòng)配置類通?;陬惵窂胶投x的bean來應(yīng)用。
 * 例如:
 * 類路徑下有tomcat-embedded.jar意味著可能想要一個(gè)TomcatServletWebServerFactory的bean
 *(除非自定義了ServletWebServerFactory的bean)
 *
 * 當(dāng)使用@SpringBootApplication注解時(shí),上下文的自動(dòng)配置功能自動(dòng)開啟。
 * 添加這個(gè)注解沒有額外的作用。
 * 
 * 自動(dòng)配置盡可能的智能,當(dāng)你自定義了更多配置,自動(dòng)配置會(huì)慢慢弱化。
 * 如果不想用某些配置,你可以通過excludeName手動(dòng)排除。
 * 也可以通過exclude排除。
 * 自動(dòng)配置總是在用戶定義bean注冊(cè)之后應(yīng)用。
 * 
 * 用@EnableAutoConfiguration注解的類包(通常通過@SpringBootApplication)具有特定的意義,通常是默認(rèn)的。
 * 例如:
 * 它將在掃描@Entity類時(shí)使用。
 * 通常建議將@EnableAutoConfiguration(如果不使用@SpringBootApplication)放在根包中,以便可以搜索所有子包和類。
 * 
 * 自動(dòng)配置類是常規(guī)的Spring @Configuration bean。
 * 它們是使用importcandidate和springfactoresloader機(jī)制定位的(與這個(gè)類相關(guān))。
 * 通常自動(dòng)配置bean是@Conditional注解的bean(最常使用@ConditionalOnClass和@ConditionalOnMissingBean注解)。
 *
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

	String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

	/**
	 * 通過class排除不需要的自動(dòng)配置類
	 */
	Class<?>[] exclude() default {};

	/**
	 * 通過類名稱排除不需要的自動(dòng)配置類
	 */
	String[] excludeName() default {};

}

4.3.1.1獲取自動(dòng)配置入口

// AutoConfigurationImportSelector
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
    if (!isEnabled(annotationMetadata)) {
        return EMPTY_ENTRY;
    }
    // exclude excludeName
    AnnotationAttributes attributes = getAttributes(annotationMetadata);
    // 所有META-INF/spring.factories中的自動(dòng)配置類
    List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
    // 去重
    configurations = removeDuplicates(configurations);
    Set<String> exclusions = getExclusions(annotationMetadata, attributes);
    checkExcludedClasses(configurations, exclusions);
    // 去掉需要排除的
    configurations.removeAll(exclusions);
    // 過濾器過濾
    configurations = getConfigurationClassFilter().filter(configurations);
    fireAutoConfigurationImportEvents(configurations, exclusions);
    return new AutoConfigurationEntry(configurations, exclusions);
}

4.3.1.2過濾器應(yīng)用

OnClassCondition過濾器會(huì)對(duì)配置類中@ConditionalOnClass和@ConditionalOnMissingClass進(jìn)行匹配過濾

 // MybatisAutoConfiguration
 @ConditionalOnClass({ SqlSessionFactory.class, SqlSessionFactoryBean.class })

如果classpath下沒有SqlSessionFactory或者SqlSessionFactoryBean,該配置類將被過濾

OnBeanCondition過濾器會(huì)對(duì)配置類中@ConditionalOnSingleCandidate進(jìn)行匹配過濾

 // MybatisAutoConfiguration
 @ConditionalOnSingleCandidate(DataSource.class)

應(yīng)用上下文中是否存在DataSource類型的單個(gè)候選 bean。如果存在且只有一個(gè)這樣的 bean,則條件匹配。

4.3.1.3過濾結(jié)果

4.3.1.4遍歷處理自動(dòng)配置類

后續(xù)就是將MybatisAutoConfiguration中涉及到的bean定義信息注冊(cè)到容器中。

五、總結(jié)

1. Spring Boot 啟動(dòng)和自動(dòng)配置的初始化

當(dāng) Spring Boot 啟動(dòng)時(shí),SpringApplication.run() 方法會(huì)被調(diào)用,Spring 容器會(huì)加載并處理配置類和自動(dòng)配置類。在自動(dòng)配置過程中,Spring Boot 會(huì)根據(jù) @EnableAutoConfiguration 注解和 @AutoConfiguration 注解掃描和加載符合條件的自動(dòng)配置類。

2. 自動(dòng)配置類的選擇

Spring Boot 自動(dòng)配置是通過 spring.factories 文件來加載的。spring.factories 文件列出了所有自動(dòng)配置類,在應(yīng)用啟動(dòng)時(shí),這些自動(dòng)配置類會(huì)被加載到 Spring 容器中。

spring.factories 文件

spring-boot-autoconfigure 模塊中,spring.factories 文件中會(huì)包含對(duì) MyBatis 自動(dòng)配置類 MybatisAutoConfiguration 的引用。該文件告訴 Spring Boot 當(dāng)滿足特定條件時(shí),加載 MybatisAutoConfiguration 類。

3. 處理 @EnableAutoConfiguration 和條件注解

Spring Boot 使用了許多條件注解(@Conditional 系列注解),來決定是否啟用某些配置類。

@ConditionalOnClass 和 @ConditionalOnMissingClass

MybatisAutoConfiguration 配置類上有 @ConditionalOnClass 注解,表示只有當(dāng) SqlSessionFactory、SqlSessionFactoryBean 等 MyBatis 相關(guān)類在類路徑中時(shí),才會(huì)啟用該自動(dòng)配置類。@ConditionalOnClassOnClassCondition 過濾器進(jìn)行檢查,判斷類路徑中是否存在這些類。

MybatisAutoConfiguration 還會(huì)使用 @ConditionalOnSingleCandidate 注解來檢查 Spring 容器中是否存在且只有一個(gè) DataSource 類型的 Bean。如果條件滿足,則加載 MybatisAutoConfiguration。

4. 加載 MybatisAutoConfiguration 配置類

在滿足了 @ConditionalOnClass@ConditionalOnSingleCandidate 等條件后,MybatisAutoConfiguration 類會(huì)被加載并注冊(cè)到 Spring 容器中。

5. 創(chuàng)建 DataSource 和 SqlSessionFactory

MybatisAutoConfiguration 配置類內(nèi)部有多個(gè) @Bean 方法,其中主要的兩個(gè)是 DataSourceSqlSessionFactory 的配置。Spring Boot 會(huì)根據(jù)現(xiàn)有的條件自動(dòng)配置這些 Bean。

DataSource

  • 如果你沒有手動(dòng)配置 DataSource,Spring Boot 會(huì)使用默認(rèn)的數(shù)據(jù)庫連接池(如 HikariCP)自動(dòng)配置一個(gè) DataSource Bean。
  • 如果已經(jīng)在應(yīng)用上下文中存在 DataSource,則自動(dòng)配置會(huì)跳過該步驟。

SqlSessionFactory

SqlSessionFactory 是 MyBatis 的核心對(duì)象,它需要 DataSource 來進(jìn)行初始化。MybatisAutoConfiguration 類會(huì)檢查容器中是否已有 SqlSessionFactory Bean,如果沒有,則會(huì)創(chuàng)建一個(gè)新的 SqlSessionFactory。

@ConditionalOnMissingBean 注解表示只有當(dāng)容器中沒有 SqlSessionFactory 時(shí),才會(huì)創(chuàng)建這個(gè) Bean。

6. 創(chuàng)建 SqlSessionTemplate

SqlSessionTemplate 是 MyBatis 與 Spring 整合的核心類,負(fù)責(zé)事務(wù)管理和會(huì)話的創(chuàng)建。MybatisAutoConfiguration 會(huì)根據(jù) SqlSessionFactory 創(chuàng)建一個(gè) SqlSessionTemplate

如果容器中沒有 SqlSessionTemplate Bean,MybatisAutoConfiguration 會(huì)創(chuàng)建并注冊(cè)一個(gè) SqlSessionTemplate Bean。

7. 配置 MapperScannerConfigurer 或 @MapperScan

Spring Boot 中的 MyBatis 自動(dòng)配置已經(jīng)提供了自動(dòng)掃描 Mapper 的功能,通常不需要手動(dòng)配置 MapperScannerConfigurer。@MapperScan 注解用于指定掃描 Mapper 接口的包:

Spring Boot 會(huì)自動(dòng)掃描該包下的 Mapper 接口,并將其注冊(cè)為 Spring Bean。

以上就是SpringBoot中的自動(dòng)裝配原理詳解的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot自動(dòng)裝配的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java?嵌入數(shù)據(jù)引擎從?SQLite?到?SPL詳解

    Java?嵌入數(shù)據(jù)引擎從?SQLite?到?SPL詳解

    這篇文章主要介紹了Java?嵌入數(shù)據(jù)引擎:從?SQLite?到?SPL,SQLite架構(gòu)簡(jiǎn)單,其核心雖然是C語言開發(fā)的,但封裝得比較好,對(duì)外呈現(xiàn)為一個(gè)小巧的Jar包,能方便地集成在Java應(yīng)用中,本文給大家介紹的非常詳細(xì),需要的朋友參考下
    2022-07-07
  • Java利用DOM解析XML的學(xué)習(xí)指南

    Java利用DOM解析XML的學(xué)習(xí)指南

    在Java中使用DOM解析XML文件是一個(gè)常見的操作,它允許你以編程方式讀取、修改和保存XML文檔的結(jié)構(gòu)和內(nèi)容,本文為大家介紹了具體的實(shí)現(xiàn)步驟,有需要的小伙伴可以參考下
    2025-04-04
  • druid連接池的參數(shù)配置示例全面解析

    druid連接池的參數(shù)配置示例全面解析

    這篇文章主要為大家介紹了druid連接池的參數(shù)配置示例全面解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • Java中JSONObject與JSONArray的使用區(qū)別詳解

    Java中JSONObject與JSONArray的使用區(qū)別詳解

    這篇文章主要介紹了Java中JSONObject與JSONArray的使用區(qū)別詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-11-11
  • Springboot?Mybatis使用pageHelper如何實(shí)現(xiàn)分頁查詢

    Springboot?Mybatis使用pageHelper如何實(shí)現(xiàn)分頁查詢

    這篇文章主要介紹了Springboot?Mybatis使用pageHelper如何實(shí)現(xiàn)分頁查詢問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • SpringBoot中@ConditionalOnProperty注解的使用方法詳解

    SpringBoot中@ConditionalOnProperty注解的使用方法詳解

    這篇文章主要介紹了SpringBoot中@ConditionalOnProperty注解的使用方法詳解,在開發(fā)基于SpringBoot框架的項(xiàng)目時(shí),會(huì)用到下面的條件注解,有時(shí)會(huì)有需要控制配置類是否生效或注入到Spring上下文中的場(chǎng)景,可以使用@ConditionalOnProperty注解來控制,需要的朋友可以參考下
    2024-01-01
  • MyBatis 探秘之#{} 與 ${} 參傳差異解碼(數(shù)據(jù)庫連接池筑牢數(shù)據(jù)交互根基)

    MyBatis 探秘之#{} 與 ${} 參傳差異解碼(數(shù)據(jù)庫連接池筑牢數(shù)據(jù)交互

    本文詳細(xì)介紹了MyBatis中的`#{}`和`${}`的區(qū)別與使用場(chǎng)景,包括預(yù)編譯SQL和即時(shí)SQL的區(qū)別、安全性問題,以及如何正確使用數(shù)據(jù)庫連接池來提高性能,感興趣的朋友一起看看吧
    2024-12-12
  • java實(shí)現(xiàn)圖片壓縮的思路與代碼

    java實(shí)現(xiàn)圖片壓縮的思路與代碼

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)圖片壓縮的思路與代碼,將較大的圖片按照指定的寬高,以寬為基準(zhǔn),或高為基準(zhǔn)按照等比例壓縮圖片,感興趣的小伙伴們可以參考一下
    2016-03-03
  • SpringBoot解析自定義yml文件的流程步驟

    SpringBoot解析自定義yml文件的流程步驟

    這篇文章主要介紹了SpringBoot解析自定義yml文件的流程步驟,文章通過代碼示例和圖文結(jié)合的方式給大家介紹的非常詳細(xì), 對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-06-06
  • SpringBoot3集成Redis的方法詳解

    SpringBoot3集成Redis的方法詳解

    緩存在項(xiàng)目開發(fā)中,基本上是必選組件之一,Redis作為一個(gè)key-value存儲(chǔ)系統(tǒng),具備極高的數(shù)據(jù)讀寫效率,并且支持的數(shù)據(jù)類型比較豐富,下面我們就來看看SpringBoot3是如何集成Redis的吧
    2023-08-08

最新評(píng)論