SpringBoot自動(dòng)裝配Import示例詳解
一、前言
@Import導(dǎo)入的類會(huì)被Spring加載到IOC容器中。而@Import提供4中用法:
導(dǎo)入Bean
導(dǎo)入配置類
導(dǎo)入 ImportSelector 實(shí)現(xiàn)類。一般用于加載配置文件中的類
導(dǎo)入 ImportBeanDefinitionRegistrar 實(shí)現(xiàn)類。
二、 定義
@Import注解定義如下,其內(nèi)部只有一個(gè)參數(shù)為Class對(duì)象數(shù)組
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Import { Class<?>[] value(); }
三、使用說(shuō)明
通過(guò)一個(gè)簡(jiǎn)單的小例子測(cè)試一下@Import是不是真的能實(shí)現(xiàn)Bean的注入
3.1 創(chuàng)建項(xiàng)目
3.1.1 導(dǎo)入依賴
這里我們除了springboot依賴,再添加個(gè)lombok依賴
<?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 https://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.3</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.ldx</groupId> <artifactId>import-annotation</artifactId> <version>0.0.1-SNAPSHOT</version> <name>import-annotation</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project>
3.1.2 創(chuàng)建User類
package com.ldx.importannotation; import lombok.AllArgsConstructor; import lombok.Data; /** * 用戶信息實(shí)體 * @author ludangxin * @date 2021/8/1 */ @Data @AllArgsConstructor public class User { public User() { this.name = "李四"; this.age = 13; } private String name; private Integer age; }
3.2 測(cè)試導(dǎo)入Bean
3.2.1 修改啟動(dòng)類
import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Import; @Slf4j // 注入U(xiǎn)serBean @Import(value = User.class) @SpringBootApplication public class ImportAnnotationApplication { public static void main(String[] args) { ConfigurableApplicationContext applicationContext = SpringApplication.run(ImportAnnotationApplication.class, args); User user = applicationContext.getBean(User.class); log.info("user info ==={}",user); } }
3.3 測(cè)試導(dǎo)入配置類
3.3.1 創(chuàng)建UserConfig類
import org.springframework.context.annotation.Bean; /** * 用戶配置類 * @author ludangxin * @date 2021/8/1 */ public class UserConfig { @Bean public User getUser(){ return new User(); } }
3.3.2 修改啟動(dòng)類
將啟動(dòng)類上的@Import的value指向UserConfig類
@Import(value = UserConfig.class)
UserBean注入成功。
3.4 測(cè)試導(dǎo)入ImportSelector
3.4.1 創(chuàng)建UseImportSelector類
import org.springframework.context.annotation.ImportSelector; import org.springframework.core.type.AnnotationMetadata; /** * 用戶Bean選擇器配置類 * @author ludangxin * @date 2021/8/1 */ public class UseImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { // 指定User類的全限類名 return new String[]{"com.ldx.importannotation.User"}; } }
3.4.2 修改啟動(dòng)類
將啟動(dòng)類上的@Import的value指向UseImportSelector類
@Import(value = UseImportSelector.class)
3.4.3 啟動(dòng)測(cè)試
UserBean注入成功。
3.5 測(cè)試導(dǎo)入ImportBeanDefinitionRegistrar類
3.5.1 創(chuàng)建UserImportBeanDefinitionRegistrar
package com.ldx.importannotation; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.core.type.AnnotationMetadata; /** * 用戶Bean定義注冊(cè)配置類 * @author ludangxin * @date 2021/8/1 */ public class UserImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { // 創(chuàng)建User類型的Bean的定義 BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition(); // 將創(chuàng)建的UserBean定義注冊(cè)到SpringRegistry中,其名稱為user registry.registerBeanDefinition("user", beanDefinition); } }
3.5.2 修改啟動(dòng)類
將啟動(dòng)類上的@Import的value指向UserImportBeanDefinitionRegistrar類
@Import(value = UserImportBeanDefinitionRegistrar.class)
3.6 小結(jié)
簡(jiǎn)介中介紹的四種方式都可以注入U(xiǎn)serBean。
好處:
- 導(dǎo)入指定的Bean或配置類。例如:由于業(yè)務(wù)需要將包路徑或者需要加載的Bean類不在@ComponentScan的掃描范圍內(nèi),這時(shí)候我們就可以通過(guò)@Import來(lái)實(shí)現(xiàn)Bean的注入。
- ImportSelector方式是制定需要加載類的全限類名。這時(shí)候我們就可以將我們的需要裝載的類寫到配置文件中,比如某個(gè)txt中,然后項(xiàng)目啟動(dòng)的時(shí)候讀取txt中的全限類名,實(shí)現(xiàn)Bean的裝載。SpringBoot就是使用這種方式實(shí)現(xiàn)的自動(dòng)裝配。
四、 改進(jìn)
上面的例子通過(guò)使用@Import注解實(shí)現(xiàn)了spring bean的自動(dòng)注入。但是裝載Bean每次都得指定Bean的類或者配置類,在生產(chǎn)環(huán)境中我們?cè)谑褂玫谌絁ar的時(shí)候根本不知道應(yīng)該使用哪個(gè)配置文件或者壓根就不知道配置文件的名稱。這時(shí)我們其實(shí)可以擴(kuò)展一個(gè)注解來(lái)優(yōu)化這個(gè)問(wèn)題。
4.1 創(chuàng)建注解
package com.ldx.importannotation; import org.springframework.context.annotation.Import; import java.lang.annotation.*; /** * 啟用User配置信息注解 * @author ludangxin * @date 2021/8/1 */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented // 指定需要導(dǎo)入的UserBean的配置類 @Import(UseImportSelector.class) public @interface EnableUser {}
4.2 修改啟動(dòng)類
注掉之前的@Import,使用剛創(chuàng)建的@EnableUser注解
import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Import; @Slf4j //@Import(value = UserImportBeanDefinitionRegistrar.class) @EnableUser @SpringBootApplication public class ImportAnnotationApplication { public static void main(String[] args) { ConfigurableApplicationContext applicationContext = SpringApplication.run(ImportAnnotationApplication.class, args); User user = applicationContext.getBean(User.class); log.info("user info ==={}",user); } }
UserBean注入成功。
思考??
SpringBoot項(xiàng)目中能不能直接獲取或者使用Jar包中的Bean呢?
五、 驗(yàn)證
5.1 創(chuàng)建項(xiàng)目
user模塊為Bean的提供者,book-manage通過(guò)引入user模塊Jar,來(lái)驗(yàn)證項(xiàng)目中能不能直接使用Jar中的Bean
5.2 創(chuàng)建user模塊
5.2.1 導(dǎo)入依賴
沒(méi)啥特別的依賴
<?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 https://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.3</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.ldx</groupId> <artifactId>user</artifactId> <version>0.0.1-SNAPSHOT</version> <name>user</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project>
5.2.2 創(chuàng)建User類
package com.ldx.user; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.ArrayList; import java.util.List; /** * 用戶信息類 * @author ludangxin * @date 2021/8/1 */ @Data @NoArgsConstructor @AllArgsConstructor public class User { private Integer id; private String name; /** * 角色狀態(tài)嗎 1.管理員 2.老師 3.學(xué)生 */ private Character role; private Integer age; public User getUserInfo() { return new User(66, "張三", '3', 21); } /** * 獲取其任課老師信息 */ public List<User> getTeachers() { List<User> users = new ArrayList<>(); User user = new User(); user.setId(2); user.setName("王麻子"); user.setAge(45); user.setRole('2'); User user1 = new User(); user1.setId(3); user1.setName("李四"); user1.setAge(35); user1.setRole('2'); users.add(user); users.add(user1); return users; } }
5.2.3 修改啟動(dòng)類
import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; @Slf4j @SpringBootApplication public class UserApplication { public static void main(String[] args) { ConfigurableApplicationContext applicationContext = SpringApplication.run(UserApplication.class, args); User user = applicationContext.getBean(User.class); user.getTeachers().forEach(obj -> log.info("user teacher info ==={} ", obj) ); } @Bean public User getUser() { return new User(); } }
5.3 創(chuàng)建book-manage模塊
5.3.1 導(dǎo)入依賴
<?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 https://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.3</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.ldx</groupId> <artifactId>book-manage</artifactId> <version>0.0.1-SNAPSHOT</version> <name>book-manage</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- user模塊依賴 --> <dependency> <groupId>com.ldx</groupId> <artifactId>user</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project>
5.3.2 修改啟動(dòng)類
直接獲取User Bean 并調(diào)用getUserInfo方法
import com.ldx.user.User; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; @Slf4j @SpringBootApplication public class BookManageApplication { public static void main(String[] args) { ConfigurableApplicationContext applicationContext = SpringApplication.run(BookManageApplication.class, args); User user = applicationContext.getBean(User.class); log.info("user info === {}", user.getUserInfo()); } }
六、 在user模塊中添加Enable注解
import org.springframework.context.annotation.Import; import java.lang.annotation.*; /** * 啟用User配置信息注解 * @author ludangxin * @date 2021/8/1 */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(User.class) public @interface EnableUser {}
七、小結(jié)
不能直接在當(dāng)前項(xiàng)目中使用Jar中的Bean(SpringBoot默認(rèn)使用ImportSelector的方式加載META-INF/spring.factories中指定的配置類,會(huì)導(dǎo)致只需要導(dǎo)入相應(yīng)的第三方Jar就可以使用其環(huán)境中的Bean)
可以在當(dāng)前項(xiàng)目中使用Jar包中提供的Enable注解來(lái)導(dǎo)入Jar的Bean配置
到此這篇關(guān)于SpringBoot自動(dòng)裝配-Import的文章就介紹到這了,更多相關(guān)SpringBoot自動(dòng)裝配Import內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
mybatis使用pagehelper插件過(guò)程詳解
這篇文章主要介紹了mybatis使用pagehelper插件過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12@RequestParam使用defaultValue屬性設(shè)置默認(rèn)值的操作
這篇文章主要介紹了@RequestParam使用defaultValue屬性設(shè)置默認(rèn)值的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-02-02Java 代碼實(shí)例解析設(shè)計(jì)模式之監(jiān)聽者模式
所謂監(jiān)聽者模式,我理解的是構(gòu)建一個(gè)容器存放所有被監(jiān)聽的線程或?qū)ο?,監(jiān)聽每個(gè)線程或?qū)ο蟀l(fā)生的變化,若某個(gè)線程或?qū)ο笥|發(fā)指定規(guī)則,那么則對(duì)所有被監(jiān)聽的線程或?qū)ο蟾鶕?jù)業(yè)務(wù)需要做處理2021-10-10spring boot 錯(cuò)誤頁(yè)面配置解決方案
這篇文章主要介紹了spring boot 錯(cuò)誤頁(yè)面配置解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10Java字符串處理全解析(String、StringBuilder與StringBuffer)
這篇文章主要介紹了Java字符串處理全解析(String、StringBuilder與StringBuffer),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧2025-04-04使用注解進(jìn)行Spring開發(fā)的全過(guò)程
使用注解(Annotation)是一種在代碼級(jí)別進(jìn)行說(shuō)明和標(biāo)記的技術(shù),它從JDK 5.0開始引入,并在現(xiàn)代Java開發(fā)中得到了廣泛應(yīng)用,本文將詳細(xì)介紹Spring框架中常用的注解及示例,幫助開發(fā)者快速掌握Spring注解開發(fā)的要點(diǎn)和技巧,需要的朋友可以參考下2023-11-11基于Java注解(Annotation)的自定義注解入門介紹
要深入學(xué)習(xí)注解,我們就必須能定義自己的注解,并使用注解,在定義自己的注解之前,我們就必須要了解Java為我們提供的元注解和相關(guān)定義注解的語(yǔ)法2013-04-04