最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot中的自動裝配原理詳解

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

前言

通過兩個簡單的案例:在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中單獨(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,無需手動查找和復(fù)制大量依賴,避免了我們?nèi)ヒ胍蕾囁鶐淼穆闊?/p>

3.2配置類及配置文件差異

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

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

四、SpringBoot怎么自動配置MyBatis

4.1MyBatis自動配置信息位置

4.2讀取自動配置信息

4.3解析bean定義信息

4.3.1解析Application中@Import

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

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

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

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

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

 // MybatisAutoConfiguration
 @ConditionalOnSingleCandidate(DataSource.class)

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

4.3.1.3過濾結(jié)果

4.3.1.4遍歷處理自動配置類

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

五、總結(jié)

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

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

2. 自動配置類的選擇

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

spring.factories 文件

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

3. 處理 @EnableAutoConfiguration 和條件注解

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

@ConditionalOnClass 和 @ConditionalOnMissingClass

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

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 會使用默認(rèn)的數(shù)據(jù)庫連接池(如 HikariCP)自動配置一個 DataSource Bean。
  • 如果已經(jīng)在應(yīng)用上下文中存在 DataSource,則自動配置會跳過該步驟。

SqlSessionFactory

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

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

6. 創(chuàng)建 SqlSessionTemplate

SqlSessionTemplate 是 MyBatis 與 Spring 整合的核心類,負(fù)責(zé)事務(wù)管理和會話的創(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中的自動裝配原理詳解的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot自動裝配的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java之jdbc連接mysql數(shù)據(jù)庫的方法步驟詳解

    Java之jdbc連接mysql數(shù)據(jù)庫的方法步驟詳解

    這篇文章主要介紹了Java之jdbc連接mysql數(shù)據(jù)庫的方法步驟詳解,JCBC技術(shù)是java開發(fā)必備的只是,jdbc連接mysql數(shù)據(jù)庫,這是一個比較簡單的方法,有興趣的可以了解一下
    2020-07-07
  • 一文徹底弄懂零拷貝原理以及java實(shí)現(xiàn)

    一文徹底弄懂零拷貝原理以及java實(shí)現(xiàn)

    零拷貝(英語: Zero-copy) 技術(shù)是指計(jì)算機(jī)執(zhí)行操作時,CPU不需要先將數(shù)據(jù)從某處內(nèi)存復(fù)制到另一個特定區(qū)域,下面這篇文章主要給大家介紹了關(guān)于零拷貝原理以及java實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • SpringCloudAlibaba分布式配置中心Nacos持久化方式

    SpringCloudAlibaba分布式配置中心Nacos持久化方式

    文章介紹了如何創(chuàng)建Nacos數(shù)據(jù)庫并初始化,修改Nacos配置文件以通過數(shù)據(jù)庫動態(tài)修改配置文件,作者分享了遇到的問題和解決方法,提醒在重啟服務(wù)器時注意MySQL是否已成功啟動
    2026-01-01
  • Java靜態(tài)代理和動態(tài)代理的深入講解

    Java靜態(tài)代理和動態(tài)代理的深入講解

    這篇文章主要給大家介紹了關(guān)于Java靜態(tài)代理和動態(tài)代理的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • Java基于logback?MessageConverter實(shí)現(xiàn)日志脫敏方案分析

    Java基于logback?MessageConverter實(shí)現(xiàn)日志脫敏方案分析

    本文介紹了一種日志脫敏方案,即基于logbackMessageConverter和正則匹配的方法,該方法的優(yōu)點(diǎn)是侵入性低,工作量少,只需修改xml配置文件,適用于老項(xiàng)目,感興趣的朋友跟隨小編一起看看吧
    2024-10-10
  • Java去掉小數(shù)點(diǎn)后面無效0的方案與建議

    Java去掉小數(shù)點(diǎn)后面無效0的方案與建議

    當(dāng)前小數(shù)點(diǎn)后面的位數(shù)過多的時候,多余的0沒有實(shí)際意義,下面這篇文章主要給大家介紹了關(guān)于Java去掉小數(shù)點(diǎn)后面無效0的方案與建議,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(28)

    Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(28)

    下面小編就為大家?guī)硪黄狫ava基礎(chǔ)的幾道練習(xí)題(分享)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧,希望可以幫到你
    2021-07-07
  • Java反射簡易教程

    Java反射簡易教程

    這篇文章主要介紹了Java反射簡易教程,小編覺得挺不錯的,這里分享給大家,需要的朋友可以參考。
    2017-11-11
  • Java注解篇之@SneakyThrows示例詳解

    Java注解篇之@SneakyThrows示例詳解

    在Java編程中異常處理是一個重要的概念,為了簡化異常處理過程,Lombok庫提供了一個名為@SneakyThrows的注解,這篇文章主要介紹了Java注解篇之@SneakyThrows的相關(guān)資料,需要的朋友可以參考下
    2025-06-06
  • mybatis-plus 批量插入示例代碼

    mybatis-plus 批量插入示例代碼

    正常我們使用mybatis-plus插入的時候,首先想到的是saveBatch方法,不過看了下打印出來的sql和底層代碼,才發(fā)現(xiàn)它并不是真正的批量插入這篇文章主要介紹了mybatis-plus 批量插入示例,需要的朋友可以參考下
    2023-07-07

最新評論

浠水县| 正宁县| 蓬莱市| 高尔夫| 南漳县| 贡嘎县| 迁安市| 阿拉尔市| 枣庄市| 仁寿县| 河池市| 大冶市| 共和县| 武陟县| 盐边县| 苍梧县| 永新县| 饶河县| 辽源市| 葵青区| 陇川县| 汕尾市| 沐川县| 密山市| 县级市| 双流县| 集贤县| 陕西省| 玉山县| 天津市| 余干县| 开阳县| 库伦旗| 公安县| 区。| 宜宾市| 邢台市| 宜阳县| 城市| 温州市| 微山县|