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太帅了---------

欧耶

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