SpringBoot自動裝配Import示例詳解
一、前言
@Import導(dǎo)入的類會被Spring加載到IOC容器中。而@Import提供4中用法:
導(dǎo)入Bean
導(dǎo)入配置類
導(dǎo)入 ImportSelector 實現(xiàn)類。一般用于加載配置文件中的類
導(dǎo)入 ImportBeanDefinitionRegistrar 實現(xiàn)類。
二、 定義
@Import注解定義如下,其內(nèi)部只有一個參數(shù)為Class對象數(shù)組
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
Class<?>[] value();
}三、使用說明
通過一個簡單的小例子測試一下@Import是不是真的能實現(xiàn)Bean的注入
3.1 創(chuàng)建項目

3.1.1 導(dǎo)入依賴
這里我們除了springboot依賴,再添加個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;
/**
* 用戶信息實體
* @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 測試導(dǎo)入Bean
3.2.1 修改啟動類
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
// 注入UserBean
@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 測試導(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 修改啟動類
將啟動類上的@Import的value指向UserConfig類
@Import(value = UserConfig.class)
UserBean注入成功。
3.4 測試導(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 修改啟動類
將啟動類上的@Import的value指向UseImportSelector類
@Import(value = UseImportSelector.class)
3.4.3 啟動測試
UserBean注入成功。
3.5 測試導(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定義注冊配置類
* @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定義注冊到SpringRegistry中,其名稱為user
registry.registerBeanDefinition("user", beanDefinition);
}
}3.5.2 修改啟動類
將啟動類上的@Import的value指向UserImportBeanDefinitionRegistrar類
@Import(value = UserImportBeanDefinitionRegistrar.class)
3.6 小結(jié)
簡介中介紹的四種方式都可以注入UserBean。
好處:
- 導(dǎo)入指定的Bean或配置類。例如:由于業(yè)務(wù)需要將包路徑或者需要加載的Bean類不在@ComponentScan的掃描范圍內(nèi),這時候我們就可以通過@Import來實現(xiàn)Bean的注入。
- ImportSelector方式是制定需要加載類的全限類名。這時候我們就可以將我們的需要裝載的類寫到配置文件中,比如某個txt中,然后項目啟動的時候讀取txt中的全限類名,實現(xiàn)Bean的裝載。SpringBoot就是使用這種方式實現(xiàn)的自動裝配。
四、 改進
上面的例子通過使用@Import注解實現(xiàn)了spring bean的自動注入。但是裝載Bean每次都得指定Bean的類或者配置類,在生產(chǎn)環(huán)境中我們在使用第三方Jar的時候根本不知道應(yīng)該使用哪個配置文件或者壓根就不知道配置文件的名稱。這時我們其實可以擴展一個注解來優(yōu)化這個問題。
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 修改啟動類
注掉之前的@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項目中能不能直接獲取或者使用Jar包中的Bean呢?
五、 驗證
5.1 創(chuàng)建項目
user模塊為Bean的提供者,book-manage通過引入user模塊Jar,來驗證項目中能不能直接使用Jar中的Bean
5.2 創(chuàng)建user模塊
5.2.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>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 修改啟動類
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 修改啟動類
直接獲取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)前項目中使用Jar中的Bean(SpringBoot默認使用ImportSelector的方式加載META-INF/spring.factories中指定的配置類,會導(dǎo)致只需要導(dǎo)入相應(yīng)的第三方Jar就可以使用其環(huán)境中的Bean)
可以在當(dāng)前項目中使用Jar包中提供的Enable注解來導(dǎo)入Jar的Bean配置
到此這篇關(guān)于SpringBoot自動裝配-Import的文章就介紹到這了,更多相關(guān)SpringBoot自動裝配Import內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
@RequestParam使用defaultValue屬性設(shè)置默認值的操作
這篇文章主要介紹了@RequestParam使用defaultValue屬性設(shè)置默認值的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02
Java 代碼實例解析設(shè)計模式之監(jiān)聽者模式
所謂監(jiān)聽者模式,我理解的是構(gòu)建一個容器存放所有被監(jiān)聽的線程或?qū)ο?,監(jiān)聽每個線程或?qū)ο蟀l(fā)生的變化,若某個線程或?qū)ο笥|發(fā)指定規(guī)則,那么則對所有被監(jiān)聽的線程或?qū)ο蟾鶕?jù)業(yè)務(wù)需要做處理2021-10-10
Java字符串處理全解析(String、StringBuilder與StringBuffer)
這篇文章主要介紹了Java字符串處理全解析(String、StringBuilder與StringBuffer),本文通過實例代碼給大家介紹的非常詳細,感興趣的朋友一起看看吧2025-04-04
基于Java注解(Annotation)的自定義注解入門介紹
要深入學(xué)習(xí)注解,我們就必須能定義自己的注解,并使用注解,在定義自己的注解之前,我們就必須要了解Java為我們提供的元注解和相關(guān)定義注解的語法2013-04-04

