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

SpringBoot中的自動裝配原理詳解

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

前言

通過兩個簡單的案例:在Spring中集成MyBatis、在SpringBoot中集成MyBatis

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

以MyBatis為例,簡單梳理自動配置過程

一、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ū)動 -->
 <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 高級配置
 ?
         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測試類

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 自動為mybatis創(chuàng)建和配置所需的bean,簡化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ū)動 -->
 <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測試類

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中單獨引入功能模塊的依賴,如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,無需手動查找和復制大量依賴,避免了我們?nèi)ヒ胍蕾囁鶐淼穆闊?/p>

3.2配置類及配置文件差異

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

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

四、SpringBoot怎么自動配置MyBatis

4.1MyBatis自動配置信息位置

4.2讀取自動配置信息

4.3解析bean定義信息

4.3.1解析Application中@Import

/**
 * 激活Spring應用上下問的自動配置功能,嘗試猜測和配置需要的bean。
 * 自動配置類通?;陬惵窂胶投x的bean來應用。
 * 例如:
 * 類路徑下有tomcat-embedded.jar意味著可能想要一個TomcatServletWebServerFactory的bean
 *(除非自定義了ServletWebServerFactory的bean)
 *
 * 當使用@SpringBootApplication注解時,上下文的自動配置功能自動開啟。
 * 添加這個注解沒有額外的作用。
 * 
 * 自動配置盡可能的智能,當你自定義了更多配置,自動配置會慢慢弱化。
 * 如果不想用某些配置,你可以通過excludeName手動排除。
 * 也可以通過exclude排除。
 * 自動配置總是在用戶定義bean注冊之后應用。
 * 
 * 用@EnableAutoConfiguration注解的類包(通常通過@SpringBootApplication)具有特定的意義,通常是默認的。
 * 例如:
 * 它將在掃描@Entity類時使用。
 * 通常建議將@EnableAutoConfiguration(如果不使用@SpringBootApplication)放在根包中,以便可以搜索所有子包和類。
 * 
 * 自動配置類是常規(guī)的Spring @Configuration bean。
 * 它們是使用importcandidate和springfactoresloader機制定位的(與這個類相關)。
 * 通常自動配置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排除不需要的自動配置類
	 */
	Class<?>[] exclude() default {};

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

}

4.3.1.1獲取自動配置入口

// AutoConfigurationImportSelector
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
    if (!isEnabled(annotationMetadata)) {
        return EMPTY_ENTRY;
    }
    // exclude excludeName
    AnnotationAttributes attributes = getAttributes(annotationMetadata);
    // 所有META-INF/spring.factories中的自動配置類
    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過濾器應用

OnClassCondition過濾器會對配置類中@ConditionalOnClass和@ConditionalOnMissingClass進行匹配過濾

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

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

OnBeanCondition過濾器會對配置類中@ConditionalOnSingleCandidate進行匹配過濾

 // MybatisAutoConfiguration
 @ConditionalOnSingleCandidate(DataSource.class)

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

4.3.1.3過濾結(jié)果

4.3.1.4遍歷處理自動配置類

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

五、總結(jié)

1. Spring Boot 啟動和自動配置的初始化

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

2. 自動配置類的選擇

Spring Boot 自動配置是通過 spring.factories 文件來加載的。spring.factories 文件列出了所有自動配置類,在應用啟動時,這些自動配置類會被加載到 Spring 容器中。

spring.factories 文件

spring-boot-autoconfigure 模塊中,spring.factories 文件中會包含對 MyBatis 自動配置類 MybatisAutoConfiguration 的引用。該文件告訴 Spring Boot 當滿足特定條件時,加載 MybatisAutoConfiguration 類。

3. 處理 @EnableAutoConfiguration 和條件注解

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

@ConditionalOnClass 和 @ConditionalOnMissingClass

MybatisAutoConfiguration 配置類上有 @ConditionalOnClass 注解,表示只有當 SqlSessionFactory、SqlSessionFactoryBean 等 MyBatis 相關類在類路徑中時,才會啟用該自動配置類。@ConditionalOnClassOnClassCondition 過濾器進行檢查,判斷類路徑中是否存在這些類。

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

4. 加載 MybatisAutoConfiguration 配置類

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

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

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

DataSource

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

SqlSessionFactory

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

@ConditionalOnMissingBean 注解表示只有當容器中沒有 SqlSessionFactory 時,才會創(chuàng)建這個 Bean。

6. 創(chuàng)建 SqlSessionTemplate

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

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

7. 配置 MapperScannerConfigurer 或 @MapperScan

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

Spring Boot 會自動掃描該包下的 Mapper 接口,并將其注冊為 Spring Bean。

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

相關文章

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

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

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

    Java利用DOM解析XML的學習指南

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    SpringBoot3集成Redis的方法詳解

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

最新評論