SpringBoot中的@Import註解的原理是什麼?
Spring中@Import註解的使用
@Import
註解算是SpringBoot自動配置原理中一個很重要的註解
認識@Import註解
先看一下原始碼
@Target
(
ElementType
。
TYPE
)
@Retention
(
RetentionPolicy
。
RUNTIME
)
@Documented
public
@interface
Import
{
/**
* {@link Configuration}, {@link ImportSelector}, {@link ImportBeanDefinitionRegistrar}
* or regular component classes to import。
*/
Class
<?>[]
value
();
}
@Import
表示要匯入的一個或多個@Configuration類
看註釋value通常是一個普通的元件,
Configuration
,
ImportSelector
,
ImportBeanDefinitionRegistrar
。
搭建專案結構用於測試
先建立一個maven工程
加入依賴
org。projectlombok
lombok
1。18。18
org。springframework
spring-context
4。3。24。RELEASE
編寫測試程式碼
Tom.java
@Data
public
class
Tom
{
private
String
color
;
private
Integer
age
;
}
AppConfig.java
@Configuration
public
class
AppConfig
{
}
App.java
public
class
App
{
public
static
void
main
(
String
[]
args
)
{
// 建立容器
AnnotationConfigApplicationContext
context
=
new
AnnotationConfigApplicationContext
(
AppConfig
。
class
);
// 獲取bean
Tom
tom
=
context
。
getBean
(
Tom
。
class
);
System
。
out
。
println
(
tom
);
}
}
@Import用法
第一種普通元件
@Import
({
要匯入的容器中的元件
})
CustomConfiguration.java
@Configuration
public
class
CustomConfiguration
{
@Bean
public
Tom
tom
()
{
Tom
tom
=
new
Tom
();
tom
。
setAge
(
11
);
tom
。
setColor
(
“紅色”
);
return
tom
;
}
}
將
AppConfig.java
加上
@Import({ CustomConfiguration。class })
@Import
({
CustomConfiguration
。
class
})
@Configuration
public
class
AppConfig
{
}
這個時候執行App已經可以獲取到Tom
第二種
ImportSelector
CustomSelector.java
public
class
CustomSelector
implements
ImportSelector
{
@Override
public
String
[]
selectImports
(
AnnotationMetadata
importingClassMetadata
)
{
return
new
String
[]
{
“com。moli。pojo。Tom”
};
}
}
將
AppConfig.java
加上
@Import({ CustomRegistrar。class })
@Import
({
CustomRegistrar
。
class
})
@Configuration
public
class
AppConfig
{
}
這個時候執行App已經可以獲取到Tom
第三種
ImportBeanDefinitionRegistrar
CustomRegistrar.java
public
class
CustomRegistrar
implements
ImportBeanDefinitionRegistrar
{
@Override
public
void
registerBeanDefinitions
(
AnnotationMetadata
importingClassMetadata
,
BeanDefinitionRegistry
registry
)
{
BeanDefinitionBuilder
builder
=
BeanDefinitionBuilder
。
genericBeanDefinition
(
Tom
。
class
);
builder
。
setScope
(
BeanDefinition
。
SCOPE_SINGLETON
);
builder
。
addPropertyValue
(
“color”
,
“灰色”
);
builder
。
addPropertyValue
(
“age”
,
“12”
);
registry
。
registerBeanDefinition
(
“tom”
,
builder
。
getBeanDefinition
());
}
}
將
AppConfig.java
加上
@Import({ CustomSelector。class })
@Import
({
CustomSelector
。
class
})
@Configuration
public
class
AppConfig
{
}
這個時候執行App已經可以獲取到Tom
最佳搭檔 - @Import通用形式
在開源軟體中大部分
@Import
中是伴隨著一個
@EnableXXX
使用的
@Target
(
ElementType
。
TYPE
)
@Retention
(
RetentionPolicy
。
RUNTIME
)
@Documented
@Import
({
CustomRegistrar
。
class
})
public
@interface
EnableTom
{
}
將
AppConfig.java
加上
@EnableTom
@EnableTom
@Configuration
public
class
AppConfig
{
}
這樣看起來,是不是有那味了。
其實SpringBoot的自動配置就是@Import的一個應用
@SuppressWarnings
(
“deprecation”
)
@Target
(
ElementType
。
TYPE
)
@Retention
(
RetentionPolicy
。
RUNTIME
)
@Documented
@Inherited
@AutoConfigurationPackage
@Import
(
EnableAutoConfigurationImportSelector
。
class
)
public
@interface
EnableAutoConfiguration
{
。。。
}
總結
直白一點使用
@Import
註解可以快速把例項加入Spring的IOC容器中
其實這三種用法也算是一種用法,就是匯入一個類到容器,容器根據類的註解型別等資訊對不同類進行不同處理;
方法一:匯入一個
Configuration
元件,元件建立了一個Tom類的Bean;
方法二:
CustomSelector
返回的類的全限定類名,實際上要匯入到容器中的元件全類名;
方法三:
ImportBeanDefinitionRegistrar
類似於第二種
ImportSelector
用法,只不過這種用法能自定義化註冊,往容器內注入一個
BeanDefinition
,然後
BeanDeiniton
在容器內轉為一個例項bean。
https://www。
cxyxiaowu。com/21197。htm
l
作者:口袋裡的貓
關注我 @Java程式設計宇宙,學習更多 Java 知識
100 道 Java 面試題彙總 PDF 下載(含答案解析和思維導圖)