@Import
@Import 註解支持導入普通 java 類,並將其聲明成一個bean。主要用於將多個分散的 java config 配置類融合成一個更大的 config 類。
- @Import 註解在 4.2 之前只支持導入配置類。
- 在4.2之後 @Import 註解支持導入普通的 java 類,並將其聲明成一個 bean。
@Import 三種使用方式
- 直接導入普通的 Java 類。
- 配合自定義的 ImportSelector 使用。
- 配合 ImportBeanDefinitionRegistrar 使用。
假如我們已經建好了一個簡單springboot項目
Configuration方式
- 創建一個普通的 Circle類
public class Circle {
public void sayHi() {
System.out.println("Circle");
}
}
- 創建一個配置類,裏面沒有顯式聲明任何的 Bean,然後將剛纔創建的 Circle 導入
@Import({Circle.class})
@Configuration
public class MainConfig {
}
- 創建controller
@RestController
public class testController {
@Autowired
private Circle circle;
@RequestMapping("/index")
public String hello() {
circle.sayHi();
return "我真帥";
}
}
- 訪問http://127.0.0.1:8080/index
控制打印出
Circle
annotation方式
- 創建TUserRole
public class TUserRole {
public void sayHi(){
System.out.println("----------TUserRole---------");
}
}
- 創建EnableTUserTRole
要讓該配置類生效,我們可以定義一個@Enable註解來驅動它。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({TUserRole.class})
public @interface EnableTUserTRole {
}
- 將註解加到main
@EnableTUserTRole
@SpringBootApplication
public class KaleldoApplication {
public static void main(String[] args) {
SpringApplication.run(KaleldoApplication.class, args);
}
}
- 添加到控制器
@RestController
public class testController {
@Autowired
private TUserRole tUserRole;
@Autowired
private Circle circle;
@RequestMapping("/index")
public String hello() {
tUserRole.sayHi();
circle.sayHi();
return "我真帥";
}
}
- 訪問http://127.0.0.1:8080/index
打印出
----------TUserRole---------
Circle
ImportSelector
如果定義太多註解,那麼在main方法上要添加太多註解…因此使用ImportSelector
ImportSelector 是一個接口,該接口中只有一個 selectImports 方法,用於返回全類名數組。所以利用該特性我們可以給容器動態導入 N 個 Bean。
因爲這兩個bean都是通過@Enable類型註解來將配置類註冊到IOC容器中,所以我們現在要做的就是將這兩個bean一次性都註冊到IOC容器中。在Spring中,要將多個類進行註冊,可以使用selector的方式。
- 創建TRole,TUser
public class TUser {
public void sayHi(){
System.out.println("-------------TUser-------------");
}
}
public class TRole {
public void sayHi() {
System.out.println("------------TRole------------");
}
}
- 創建ApplicationSelector
public class ApplicationSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{
TRole.class.getName(),
TUser.class.getName()
};
}
}
- 創建EnableApplicationSelector
通過selectImports方法,我們一次性導入了TRole、TUser這兩個類。
要讓上面的代碼生效,我們還需將ApplicationSelector 註冊到IOC容器中。同之前的做法,我們可以通過註解的方式來實現。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({ApplicationSelector.class})
public @interface EnableApplicationSelector {
}
- 試驗
添加到main
@EnableApplicationSelector
@EnableTUserTRole
@SpringBootApplication
public class KaleldoApplication {
public static void main(String[] args) {
SpringApplication.run(KaleldoApplication.class, args);
}
}
Controller
@RestController
public class testController {
@Autowired
private TUserRole tUserRole;
@Autowired
private TUser tUser;
@Autowired
private TRole tRole;
@Autowired
private Circle circle;
@RequestMapping("/index")
public String hello() {
tUserRole.sayHi();
tUser.sayHi();
tRole.sayHi();
circle.sayHi();
return "我真帥";
}
}
訪問http://127.0.0.1:8080/index
打印
----------TUserRole---------
-------------TUser-------------
------------TRole------------
Circle
ImportBeanDefinitionRegistrar
ImportBeanDefinitionRegistrar 是一個接口,它可以手動註冊bean到容器中,從而可以對類進行個性化的定製。
- 創建TMenu
public class TMenu {
public void sayHi(){
System.out.println("-----------Kaleldo太帥了---------");
}
}
- 創建EImportBeanDefinitionRegistrar
public class EImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(TMenu.class);
// 註冊一個名字叫做 kaleldo 的 bean
beanDefinitionRegistry.registerBeanDefinition("kaleldo", rootBeanDefinition);
}
}
- 注入ioc
@Import({Circle.class, EImportBeanDefinitionRegistrar.class})
@Configuration
public class MainConfig {
}
- 試驗
@RestController
public class testController {
@Autowired
private TUserRole tUserRole;
@Autowired
private TUser tUser;
@Autowired
private TRole tRole;
@Autowired
private Circle circle;
@Resource(name = "kaleldo")
private TMenu tMenu;
@RequestMapping("/index")
public String hello() {
tUserRole.sayHi();
tUser.sayHi();
tRole.sayHi();
circle.sayHi();
tMenu.sayHi();
return "我真帥";
}
}
訪問http://127.0.0.1:8080/index
----------TUserRole---------
-------------TUser-------------
------------TRole------------
Circle
-----------Kaleldo太帥了---------
歐耶