Spring Boot基础(二)自动配置的基石:Import注解


Enbale的基本:Import注解

@Enbale底层依赖于@Import注解导入一些类,使用Import导入的类会被Spring加载到IoC容器中,而@Import提供了4中用法:

  • 导入Bean:直接导入实体类
  • 导入配置类:导入配置类中定义的所有Bean
  • 导入ImportSelect实现类,用于加载配置文件中的类
  • 导入ImportBeanDefinitionRegistrar实现类

直接导入Bean

@SpringBootApplication
@Import(User.class)   //导入实体类
public class SprintbootMyUnApplication {

    public static void main(String[] args) {
        //启动SpringBoot,获取Ioc
        ConfigurableApplicationContext context = SpringApplication.run(SprintbootMyUnApplication.class, args);
     //直接根据实体类的class获取bean
        User bean = context.getBean(User.class);
     //获得的是一个map,从map中可以查看Bean的名称,一般是类的全限定名 Map
beans = context.getBeansOfType(User.class);
System.out.println(bean); System.out.println(beans); }

导入配置类

@SpringBootApplication
//UserConfig中定义的所有类,都会被创建
@Import(UserConfig.class)
//@EnableUser
//@Import(User.class)
public class SprintbootMyUnApplication {

    public static void main(String[] args) {
        //启动SpringBoot,获取Ioc
        ConfigurableApplicationContext context = SpringApplication.run(SprintbootMyUnApplication.class, args);
      Object user = context.getBean("user153"); Object role = context.getBean("role"); System.out.println(user); System.out.println(role); }

配置类(注意包名要对上):

@Configuration //当使用Import注解导入这个配置类时,这个注解可加可不加
public class UserConfig {

    @Bean
    public User user153(){
        return new User();
    }
    @Bean
    public Role role(){
        return new Role();
    }
}

导入ImportSelect实现类

Spring Boot官方就是用的这种方式,路径:@SpringBootApplication——>@EnableAutoConfiguration——>@Import(AutoConfigurationImportSelector.class)——>AutoConfigurationImportSelector。

AutoConfigurationImportSelector实现了DeferredImportSelector接口,而DeferredImportSelector实现了ImportSelector接口。后面会详细介绍这个实现类

@SpringBootApplication
//imports实现了ImportSelect接口的实现类,也可以导入Bean
@Import(MyImportSelector.class)
public class SprintbootMyUnApplication {

    public static void main(String[] args) {
        //启动SpringBoot,获取Ioc
        ConfigurableApplicationContext context = SpringApplication.run(SprintbootMyUnApplication.class, args);

        Object user = context.getBean(User.class);
        Object role = context.getBean(Role.class);
        System.out.println(user);
        System.out.println(role);
    }

实现类:

public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
     //这里的字符串可以动态替换
return new String[]{"com.yz.domin.Role","com.yz.domin.User"}; } }

导入ImportBeanDefinitionRegistrar实现类

@SpringBootApplication
//@ComponentScan("com.yz.config")
//@Import(UserConfig.class)
//@EnableUser
//@Import(User.class)
//@Import(MyImportSelector.class)
@Import(MyImportBeanDefinitionRegistrar.class)
public class SprintbootMyUnApplication {

    public static void main(String[] args) {
        //启动SpringBoot,获取Ioc
        ConfigurableApplicationContext context = SpringApplication.run(SprintbootMyUnApplication.class, args);
     //导入User,因为Role没有被创建
        Object user = context.getBean("user88");
        //Object role = context.getBean(Role.class);
        System.out.println(user);
        //System.out.println(role);
    }

实现类:

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        //手动向Ioc容器里注入Bean
        //定义bean的类型
        AbstractBeanDefinition definition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition();
        //定义bean的名字
        registry.registerBeanDefinition("user88", definition);
    }
}

 EnableAutoConfiguration注解