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)入依賴
沒啥特別的依賴
<?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)文章希望大家以后多多支持腳本之家!
- 深入淺析SpringBoot中的自動(dòng)裝配
- springboot?無(wú)法自動(dòng)裝配的問(wèn)題
- SpringBoot自動(dòng)裝配原理詳解
- 淺談springboot自動(dòng)裝配原理
- springboot之自動(dòng)裝配全過(guò)程
- SpringSecurity在SpringBoot中的自動(dòng)裝配過(guò)程
- 淺析SpringBoot自動(dòng)裝配的實(shí)現(xiàn)
- SpringBoot自動(dòng)裝配原理解析
- SpringBoot中的自動(dòng)裝配原理解析
- SpringBoot自動(dòng)裝配注解的實(shí)現(xiàn)示例
相關(guān)文章
詳解mybatis-plus配置找不到Mapper接口路徑的坑
這篇文章主要介紹了詳解mybatis-plus配置找不到Mapper接口路徑的坑,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10
java中面向?qū)ο蟮母拍罴爸R(shí)點(diǎn)總結(jié)
在本篇文章里小編給大家整理的是一篇關(guān)于java中面向?qū)ο蟮母拍罴爸R(shí)點(diǎn)總結(jié)內(nèi)容,有興趣的朋友們可以參考下。2021-01-01
Java?EventBus手把手帶你實(shí)現(xiàn)
EventBus是Guava的事件處理機(jī)制,是設(shè)計(jì)模式中觀察者模式(生產(chǎn)/消費(fèi)者編程模型)的優(yōu)雅實(shí)現(xiàn)。本文就來(lái)和大家聊聊EventBus的使用,需要的可以參考一下2023-01-01
Java不指定長(zhǎng)度的二維數(shù)組實(shí)例
今天小編就為大家分享一篇Java不指定長(zhǎng)度的二維數(shù)組實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-07-07
Springcloud Stream消息驅(qū)動(dòng)工具使用介紹
SpringCloud Stream由一個(gè)中間件中立的核組成,應(yīng)用通過(guò)SpringCloud Stream插入的input(相當(dāng)于消費(fèi)者consumer,它是從隊(duì)列中接收消息的)和output(相當(dāng)于生產(chǎn)者producer,它是發(fā)送消息到隊(duì)列中的)通道與外界交流2022-09-09

