【springboot】@Import的用法,与@ImportAutoConfiguration的区别

@Import用法

@Import的value值,可以是 普通bean、ImportSelector类、ImportBeanDefinitionRegistrar类

配置类

package org.hopehomi.boot.config;

import org.hopehomi.boot.config.selector.MyImportSelector;
import org.hopehomi.boot.model.BeanByImport;
import org.hopehomi.core.tool.support.ForDebuggerImportBeanDefinitionRegistrar;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

/**
 * @author Ledison
 * @date 2023/3/16
 */
@Configuration(proxyBeanMethods = false)
@Import({ForDebuggerImportBeanDefinitionRegistrar.class, BeanByImport.class, MyImportSelector.class})
// @ImportAutoConfiguration 如果没有写value,会去spring.factories里面找key为当前类名的value
// 如果写了value,和@Import一样
@ImportAutoConfiguration
public class MyConfig {

    public MyConfig() {
        System.out.println("MyConfig construct");
    }

    @Bean(initMethod = "doInit")
    public ConfigInnerBean getConfigInnerBean() {
        return new ConfigInnerBean();
    }
}

  1. 普通bean
package org.hopehomi.boot.model;

/**
 * @author Ledison
 * @date 2023/3/24
 */
public class BeanByImport {

}
  1. ImportBeanDefinitionRegistrar

package org.hopehomi.core.tool.support;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

/**
 * @author Ledison
 * @date 2023/3/21
 */
public class ForDebuggerImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        System.out.println("ForDebuggerImportBeanDefinitionRegistrar registerBeanDefinitions - B");
        BeanDefinition bd = new GenericBeanDefinition();
        bd.setBeanClassName("org.hopehomi.core.tool.support.HopeRegisterBean");
        registry.registerBeanDefinition("HopeRegisterBean", bd);
    }
}

  1. ImportSelector
package org.hopehomi.boot.config.selector;

import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;

/**
 * {@link org.hopehomi.boot.model.BeansByImportSelector}
 *
 * @author Ledison
 * @date 2023/3/24
 */
public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{"org.hopehomi.boot.model.BeansByImportSelector"};
    }
}

原理

三个类型都是通过ConfigurationClassParser的processImports来解析,调用方可以是@ComponentScan扫描类、spring自动装配类

  1. 引入类为ImportSelector
    通过构造器实例化类,判断是否为DeferredImportSelector的实现(延迟引入,spring的自动装配AutoConfigurationImportSelector就实现了这个接口),如果是DeferredImportSelector的实现,放入延迟Selector集合后面处理;如果不是DeferredImportSelector的实现,调用ImportSelector的selectImports方法,返回类名数组,加载解析类名(如果没有引入该类,会报错),最后这些类名数组再递归调用processImports方法
    在这里插入图片描述
  2. 引入类为ImportBeanDefinitionRegistrar
    通过构造器实例化类,加入到ConfigurationClass的importBeanDefinitionRegistrars集合中,解析完所有加载类之后,在进行处理。
    ConfigurationClassPostProcessor - processConfigBeanDefinitions - this.reader.loadBeanDefinitions(configClasses);
    执行过程在ImportSelector之后
    在这里插入图片描述
    这里的configClass.getImportBeanDefinitionRegistrars()。就是之前解析出来待处理的importBeanDefinitionRegistrars
    在这里插入图片描述
    执行回调
    在这里插入图片描述
  3. 引入类为普通类
    执行processConfigurationClass方法,引入的类会判断是否存在注解@Component、@PropertySources、@ComponentScans、@Import、@ImportResource、@Bean Method,存在的话进行对应处理。最后将类名放到ConfigurationClassParser.configurationClasses中,详细解析源码可看之前的文章。在这里没有进行类的实例化操作
    在这里插入图片描述

@ImportAutoConfiguration用法

@ImportAutoConfiguration 如果没有写value,会去spring.factories里面找key为当前类名的value
如果写了value,和@Import一样,不会通过spring.factories加载
@ImportAutoConfiguration 和 @Import不要同时在配置类使用,否则@Import里面的value会实例化两次

配置类

package org.hopehomi.boot.config;

import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.context.annotation.Configuration;

/**
 * @author Ledison
 * @date 2023/3/24
 */
// @ImportAutoConfiguration 如果没有写value,会去spring.factories里面找key为当前类名的value
// 如果写了value,和@Import一样
@ImportAutoConfiguration
@Configuration(proxyBeanMethods = false)
public class MyImportAutoConfiguration {
}

注入类

package org.hopehomi.boot.model;

import org.hopehomi.boot.config.MyImportAutoConfiguration;

/**
 * @author Ledison
 * @date 2023/3/24
 */
public class BeanByImportAutoConfiguration extends MyImportAutoConfiguration {

    public BeanByImportAutoConfiguration() {
        System.out.println("BeanByImportAutoConfiguration construct");
    }
}

spring.factories
在这里插入图片描述

原理

进入@ImportAutoConfiguration,可以看到@Import(ImportAutoConfigurationImportSelector.class)
ImportAutoConfigurationImportSelector是DeferredImportSelector的实现类,具体源码就不分析了,可以通过延迟加载Selector的步骤找到这个实现类看逻辑
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值