@Import注解用法

@Import是Spring基于 Java 注解配置的主要组成部分。接收一个Class类数组,把类加入Spring IOC容器。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
    Class<?>[] value();
}

方式一:class类数组

  • 创建ClassA类
public class ClassA {

    public void print(){
        System.out.println("this is ClassA !!!");
    }

}
  • 通过@Import引入ClassA
@Import({ClassA.class})
@Configuration
public class ImportConfig {
    
}
  • @Autowired注入ClassA测试
@SpringBootTest
class ImportApplicationTests {
    
    @Autowired
    ClassA classA;

    @Test
    void contextLoads() {
        this.classA.print();
    }

}

输出:this is ClassA !!!

方式二:实现ImportSelector接口

  • 创建ClassB类
public class ClassB {
    
    public void print(){
        System.out.println("this is ClassB !!!");
    }
}
  • 创建TestImportSelector类实现ImportSelector接口,返回包含ClassB类的数组
public class TestImportSelector implements ImportSelector {
    
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{"com.example.xx.xx.ClassB"};
    }
}
  • @Import引入TestImportSelector.class
@Import({TestImportSelector.class})
@Configuration
public class ImportConfig {
    
}
  • @Autowired注入ClassB测试
@SpringBootTest
class ImportApplicationTests {
    
    @Autowired
    ClassB classB;
    
    @Test
    void contextLoads() {
        this.classB.print();
    }
    
}

输出:this is ClassB !!!

方式三:实现ImportBeanDefinitionRegistrar接口

  • 创建ClassC类
public class ClassC {
    public void print(){
        System.out.println("this is ClassC !!!");
    }
}
  • 创建ImportBean类实现ImportBeanDefinitionRegistrar接口
public class ImportBean implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        RootBeanDefinition root = new RootBeanDefinition(ClassC.class);
        registry.registerBeanDefinition("classC", root);
    }
}

  • @Import引入ImportBean类
@Import({ImportBean.class})
@Configuration
public class ImportConfig {
    
}

  • @Autowired注入ClassC测试
@SpringBootTest
class ImportApplicationTests {

    @Autowired
    ClassC classC;

    @Test
    void contextLoads() {
        this.classC.print();
    }

}

输出:this is ClassC !!!

三种方式可以同时用

@Import({ClassA.class, TestImportSelector.class, ImportBean.class})
@Configuration
public class ImportConfig {
    
}
class ImportApplicationTests {

    @Autowired
    ClassA classA;
    @Autowired
    ClassB classB;
    @Autowired
    ClassC classC;

    @Test
    void contextLoads() {
        this.classA.print();
        this.classB.print();
        this.classC.print();
    }

}

输出:
this is ClassA !!!
this is ClassB !!!
this is ClassC !!!

自动配置原理

  • @Import引入AutoConfigurationImportSelector.class

在这里插入图片描述

  • selectImports()方法

在这里插入图片描述

  • getAutoConfigurationEntry()方法

在这里插入图片描述

  • loadFactoryNames()方法

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

最终读取的是META-INF目录下的spring.factories文件和spring-autoconfigure-metadata.properties配置文件。
在这里插入图片描述

自定义starter

1、创建一个SpringBoot项目
2、编写StarterDemo.java

public class StarterDemo {

    private String starterName;

    public StarterDemo(String starterName) {
        this.starterName = starterName;
    }

    public String getStarterName() {
        return starterName;
    }

    public void setStarterName(String starterName) {
        this.starterName = starterName;
    }
}

3、编写StarterConfig配置类

public class StarterConfig {

    @Value("${starter.name}")
    private String starterName;

    @Bean
    public StarterDemo starterDemo() {
        return new StarterDemo(starterName);
    }
}

4、在resource目录下创建一个META-INF文件夹并新建spring.factories文件

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.example.mystarter.config.StarterConfig

5、在另外的SpringBoot项目引入my-starter,并创建配置属性starter.name

<dependency>
  <groupId>com.example</groupId>
  <artifactId>my-starter</artifactId>
  <version>0.0.1-SNAPSHOT</version>
</dependency>
starter:
  name: my-starter

6、测试

@SpringBootTest
class MyApplicationTests {

    @Autowired
    private StarterDemo starterDemo;

    @Test
    void contextLoads() {
        System.out.println(starterDemo.getStarterName());
    }

}

输出:my-starter


版权声明:本文为qq_36700462原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_36700462/article/details/126452644