Spring 花裏胡哨的@Import用法

在這裏插入圖片描述

@Import

@Import 註解支持導入普通 java 類,並將其聲明成一個bean。主要用於將多個分散的 java config 配置類融合成一個更大的 config 類。

  • @Import 註解在 4.2 之前只支持導入配置類。
  • 在4.2之後 @Import 註解支持導入普通的 java 類,並將其聲明成一個 bean。

@Import 三種使用方式

  • 直接導入普通的 Java 類。
  • 配合自定義的 ImportSelector 使用。
  • 配合 ImportBeanDefinitionRegistrar 使用。

靈感來源於

假如我們已經建好了一個簡單springboot項目

Configuration方式

  1. 創建一個普通的 Circle類
public class Circle {
    public void sayHi() {
        System.out.println("Circle");
    }
}
  1. 創建一個配置類,裏面沒有顯式聲明任何的 Bean,然後將剛纔創建的 Circle 導入
@Import({Circle.class})
@Configuration
public class MainConfig {

}
  1. 創建controller
@RestController
public class testController {

 @Autowired
    private Circle circle;

    @RequestMapping("/index")
    public String hello() {
    	circle.sayHi();
        return "我真帥";
    }
}

  1. 訪問http://127.0.0.1:8080/index
    控制打印出
Circle

annotation方式

  1. 創建TUserRole
public class TUserRole {

    public void sayHi(){
        System.out.println("----------TUserRole---------");
    }
}
  1. 創建EnableTUserTRole
    要讓該配置類生效,我們可以定義一個@Enable註解來驅動它。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({TUserRole.class})
public @interface EnableTUserTRole {
}
  1. 將註解加到main
@EnableTUserTRole
@SpringBootApplication
public class KaleldoApplication {
    public static void main(String[] args) {
        SpringApplication.run(KaleldoApplication.class, args);
    }
}
  1. 添加到控制器

@RestController
public class testController {

    @Autowired
    private TUserRole tUserRole;
    @Autowired
    private Circle circle;

    @RequestMapping("/index")
    public String hello() {
        tUserRole.sayHi();
        circle.sayHi();
        return "我真帥";
    }
}
  1. 訪問http://127.0.0.1:8080/index
    打印出
----------TUserRole---------
Circle

ImportSelector

如果定義太多註解,那麼在main方法上要添加太多註解…因此使用ImportSelector
ImportSelector 是一個接口,該接口中只有一個 selectImports 方法,用於返回全類名數組。所以利用該特性我們可以給容器動態導入 N 個 Bean。
因爲這兩個bean都是通過@Enable類型註解來將配置類註冊到IOC容器中,所以我們現在要做的就是將這兩個bean一次性都註冊到IOC容器中。在Spring中,要將多個類進行註冊,可以使用selector的方式。

  1. 創建TRole,TUser
public class TUser {

    public void sayHi(){
        System.out.println("-------------TUser-------------");
    }
}
public class TRole {
    public void sayHi() {
        System.out.println("------------TRole------------");
    }
}
  1. 創建ApplicationSelector
public class ApplicationSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        return new String[]{
                TRole.class.getName(),
                TUser.class.getName()
        };
    }
}
  1. 創建EnableApplicationSelector

通過selectImports方法,我們一次性導入了TRole、TUser這兩個類。
要讓上面的代碼生效,我們還需將ApplicationSelector 註冊到IOC容器中。同之前的做法,我們可以通過註解的方式來實現。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({ApplicationSelector.class})
public @interface EnableApplicationSelector {
}
  1. 試驗
    添加到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到容器中,從而可以對類進行個性化的定製。

  1. 創建TMenu
public class TMenu {

    public void sayHi(){
        System.out.println("-----------Kaleldo太帥了---------");
    }
}

  1. 創建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);
    }
}
  1. 注入ioc

@Import({Circle.class, EImportBeanDefinitionRegistrar.class})
@Configuration
public class MainConfig {

}
  1. 試驗
@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太帥了---------

歐耶

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章