springboot项目如何将项目外部配置类纳入spring ioc容器

项目外部指的是非SpringBootApplication应用主程序类所在同层级包下的类,当我们启动一个SpringBootApplication应用主程时,应用程序会自动扫描该类同层级包下的所有类,并将带有@Configuation、@Component以及@Component的扩展注解(@Controller、@Service、@Respistory等等)注解的类注册Bean,并纳入Spring Ioc容器,此外配置类中被@Bean标注的方法也会被注册为Bean,并纳入Spring Ioc容器

那我们如何才能将项目外部的配置类注册成Bean并纳入到自己的Spring Ioc容器呢?目前我知道的有三种方法,分别是@ComponentScan、spring.factories、@Import。下面我将分析这三种方法的执行逻辑,以便理解。

1、@ComponentScan

通过在SpringBootApplication应用主程序上添加 @ComponentScan 注解并在参数中填入外部配置类包的全限定类名,让主程序在启动时主动的根据该路径去扫描,如果扫描到带有@Configuation或者@Component等注解的类,则将其注册为Bean,并纳入自己的Spring Ioc容器。

@SpringBootApplication
@ComponentScan(basePackages = {
        "com.xxx.xxx.config"})
public class WebApplication {

    public static void main(String[] args) {
        SpringApplication.run(WebApplication.class, args);
    }
}

2、spring.factories

通过在Resource文件夹下新建META-INF文件夹并在其中新建spring.factories配置文件。该配置文件的作用是当我们将项目外部功能模块作为依赖引入到本项目时,主程序会通过加载指定路径下的配置文件也就是Resource->META-INF->spring.factories路径,最终通过加载spring.factories文件来确定引入的依赖中哪些配置类需要注册为Bean,并纳入自己的Spring Ioc容器。这也是为什么我们在引入了第三方的starter依赖时,也能够使用一些不是自己注册的Bean的原因。

// 加载到此配置时会将com.blog.common.mybatis路径下的MybatisPlusAutoConfiguation配置类注册为Bean并纳入自己IOC容器
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.blog.common.mybatis.MybatisPlusAutoConfiguation

3、@Import

@Import注解最常见的就是用在注解上,在使用注解时,应用程序在扫描到注解后会将@Import注解引入的配置类注册成Bean,同时将该配置类下被@Bean注解标注的方法也一起注册为Bean,并纳入自己的Spring Ioc容器。一般来说,被@Import注解标注的注解都带有Enable前缀,用于开启某种功能,比如:@EnableDiscoveryClient注解就是用来开启服务发现功能,具体这个注解干了什么,我们通过分析其源码不难发现,这个注解其实就是通过@Import引入了EnableDiscoveryClientImportSelector.class这个导入选择器,然后通过这个导入选择器去选择注入一些Bean

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({EnableDiscoveryClientImportSelector.class})    // 引入导入选择器
public @interface EnableDiscoveryClient {
    boolean autoRegister() default true;
}

// 我们在使用@Import注解时也可以直接导入配置类


@Order(2147483547)
public class EnableDiscoveryClientImportSelector extends SpringFactoryImportSelector<EnableDiscoveryClient> {
    public EnableDiscoveryClientImportSelector() {
    }

    // 具体的导入选择执行方法
    public String[] selectImports(AnnotationMetadata metadata) {
        String[] imports = super.selectImports(metadata);
        AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(this.getAnnotationClass().getName(), true));
        boolean autoRegister = attributes.getBoolean("autoRegister");
        if (autoRegister) {
            List<String> importsList = new ArrayList(Arrays.asList(imports));
            importsList.add("org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationConfiguration");
            imports = (String[])importsList.toArray(new String[0]);
        } else {
            Environment env = this.getEnvironment();
            if (ConfigurableEnvironment.class.isInstance(env)) {
                ConfigurableEnvironment configEnv = (ConfigurableEnvironment)env;
                LinkedHashMap<String, Object> map = new LinkedHashMap();
                map.put("spring.cloud.service-registry.auto-registration.enabled", false);
                MapPropertySource propertySource = new MapPropertySource("springCloudDiscoveryClient", map);
                configEnv.getPropertySources().addLast(propertySource);
            }
        }

        return imports;
    }

    protected boolean isEnabled() {
        return (Boolean)this.getEnvironment().getProperty("spring.cloud.discovery.enabled", Boolean.class, Boolean.TRUE);
    }

    protected boolean hasDefaultFactory() {
        return true;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙茶清欢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值