SpringBoot自动装载

SpringBoot中的自动装载(1)ImportSelector接口ImportSelector接口是Spring导入外部配置的核心接口,在SpringBoot的自动化配置和@EnableXXX(功能性注解)中起到了决定性的作用。当在@Configuration标注的Class上使用@Import引入了一个ImportSelector实现类后,会把ImportSelector实现类中返回的Class名称都定义为bean。public interface ImportSelector { St
摘要由CSDN通过智能技术生成

SpringBoot中的自动装载

(1)ImportSelector接口

ImportSelector接口是Spring导入外部配置的核心接口,在SpringBoot的自动化配置和@EnableXXX(功能性注解)中起到了决定性的作用。当在@Configuration标注的Class上使用@Import引入了一个ImportSelector实现类后,会把ImportSelector实现类中返回的Class名称都定义为bean。

public interface ImportSelector {
   
    String[] selectImports(AnnotationMetadata var1);
}

DeferredImportSelector接口继承ImportSelector,他和ImportSelector的区别在于装载bean的时机上,DeferredImportSelector需要等所有的@Configuration都执行完毕后才会进行装载

public interface DeferredImportSelector 
					extends ImportSelector {
   
 //...省略
}

(2)模拟SpringBoot自动装配的实现

接下来我们写一个小例子,看下ImportSelector接口的用法

通过模拟实现ImportSelector接口来还原SpringBoot自动装配的原理(SpringBoot的自动装配原理就是通过封装ImportSelector接口等一些列操作来实现的)

1)定义Bean对象

这个类模拟的是我们要自动专配在SpringBoot容器中的Bean实例

public class User {
   
 private String username;
 private Integer age;
 //省略..
}

2)定义配置类Configuration

//定义一个configuration 
//注意这里并没有使用spring注解
//spring扫描的时候并不会装载该类
public class UserConfiguration {
   
 @Bean
 public User getUser() {
   
 return new User("张三",18);
 }
}

3 ) 定义ImportSelector接口的实现类

ImportSelector 接口中的selectImports方法会将加载的类当作一个配置类来初始化,就是相当于@Configuration注解的功能。

public class UserImportSelector implements ImportSelector {
   
 @Override
 public String[] selectImports(AnnotationMetadata importingClassMetadata) {
   
        //获取配置类名称
 return new String[]{
   UserConfiguration.class.getName()};
 }
}

4) 定义EnableXXX注解

在SpringBoot在自动装配正式通过注解@EnableAutoCofiguration注解实现的,这里通过自定义EnableXXX注解模拟SpringBoot中的@EnableAutoConfiguration注解实现自动装配。

@SpringBoot源码:在这里插入图片描述

@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target(ElementType.TYPE)
@Import(UserImportSelector.class)
public @interface EnableUserBean {
   
}

5 ) 测试

/**
* 通过在类上声明@EnableUserBean,会自动的加载所有对象
*/
@EnableUserBean
public class TestApplication {
   
 public static void main(String[] args) {
   
 //获取sprinboot注解驱动的容器对象
 AnnotationConfigApplicationContext applicationContext =new AnnotationConfigApplicationContext(TestApplication.class);
 //加载通过实现ImportSelector接口模拟SpringBoot自动装载功能,将声明的User对象的实例装配到SpringBoot的容器中
 //获取SpringBoot容器中的User的实例对象
 User user = applicationContext.getBean(User.class);
 System.out.println(user);
 }
}

由此可见,User对象并没有使用Spring的对象创建注解声明(@Controller,@Service,@Repostiroty),而是使用编程的方式动态的载入bean。

这个接口在哪里调用呢?我们可以来看一下ConfigurationClassParser这个类的processImports方法

private void processImports(ConfigurationClass configClass, SourceClass
currentSourceClass,
            Collection<SourceClass> importCandidates, boolean
checkForCircularImports) {
   
        if (importCandidates.isEmpty()) {
   
            return;
       }
        if (checkForCircularImports && isChainedImportOnStack(configClass)) {
   
            this.problemReporter.error(new CircularImportProblem(configClass, 
this.importStack));
       }
        else {
   
            this.importStack.push(configClass);
            try {
   
                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值