前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >17-SpringBoot自动配置-@Import详解

17-SpringBoot自动配置-@Import详解

作者头像
Devops海洋的渔夫
发布2022-03-23 16:12:06
2510
发布2022-03-23 16:12:06
举报
文章被收录于专栏:Devops专栏Devops专栏

17-SpringBoot自动配置-@Import详解

@Import详解

@Enable*底层依赖于@Import注解导入一些类,使用@Import导入的类会被Spring加载到 IOC 容器中。

而 @Import 提供 4种用法:

  • 导入Bean
  • 导入配置类
  • 导入 ImportSelector 实现类。一般用户加载配置文件中的类
  • 导入 ImportBeanDefinitionRegistrar 实现类

案例演示

我们接着上一篇的项目继续演示。

1.【springboot-enable】使用@Import 导入 User 类

代码语言:javascript
复制
@SpringBootApplication
@Import(User.class)
public class SpringbootEnableApplication {

    public static void main(String[] args) {
        // 获取IOC容器
        ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);
        // 其他工程
        Object user = context.getBean("user");
        System.out.println(user);
    }
}

其实使用 @Import(User.class) 是可以导入 bean 的,只是 bean 的名称不是 user,所以打印获取不到 user 名称的 bean,

我们不通过名称来获取 bean,采用类型来获取 bean,如下:

代码语言:javascript
复制
@SpringBootApplication
@Import(User.class)
public class SpringbootEnableApplication {

    public static void main(String[] args) {
        // 获取IOC容器
        ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);
        // 其他工程
//        Object user = context.getBean("user");
        Object user = context.getBean(User.class); // 使用类获取bean
        System.out.println(user);
    }

}

2.【springboot-enable】获取 IOC 容器中的 bean 映射 map

当然,如果我们希望获取类 bean 的名称,可以这样获取,如下:

代码语言:javascript
复制
@SpringBootApplication
@Import(User.class)
public class SpringbootEnableApplication {

    public static void main(String[] args) {
        // 获取IOC容器
        ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);
        // 其他工程
        Object user = context.getBean(User.class);
        System.out.println(user);

        // 获取bean的名称
        Map<String, User> map = context.getBeansOfType(User.class);
        System.out.println(map);
    }

}

3.【springboot-enable】使用@Import 导入 UserConfig 配置类

在上一篇中我们已经使用过导入配置类来获取 bean 了,不过之前我们的配置类只定义返回一个 bean 方法。现在我们来定义返回两个 bean。

3.1 【springboot-enable-other】新增 Role 类 以及配置 UserConfig 配置类返回 role bean

Role

代码语言:javascript
复制
package com.lijw.springbootenableother.domain;

public class Role {
}

UserConfig

代码语言:javascript
复制
package com.lijw.springbootenableother.config;

import com.lijw.springbootenableother.domain.Role;
import com.lijw.springbootenableother.domain.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class UserConfig {

    @Bean
    public User user(){
        return new User();
    }

    @Bean
    public Role role(){
        return new Role();
    }
}
3.2 【springboot-enable】使用@Import 导入 UserConfig 配置类,验证获取配置类中的所有 bean
代码语言:javascript
复制
package com.lijw.springbootenable;

import com.lijw.springbootenableother.config.UserConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;

import java.util.Map;

@SpringBootApplication
@Import(UserConfig.class)
public class SpringbootEnableApplication {

    public static void main(String[] args) {
        // 获取IOC容器
        ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);
        // 其他工程
        Object user = context.getBean("user");
        System.out.println(user);

        Object role = context.getBean("role");
        System.out.println(role);
    }

}

通过结果来看,@Import 导入配置类是可以将配置类中定义的 @Bean 都放入的 IOC 容器内。

另外,如果是 @Import 导入的配置类,是不需要添加配置类注解 @Configuration 也可以配识别的,如下:

image-20220225130325914

4.【springboot-enable】导入 ImportSelector 实现类

4.1 首先搜索查看一下 ImportSelector 接口
代码语言:javascript
复制
public interface ImportSelector {

   /**
    * Select and return the names of which class(es) should be imported based on
    * the {@link AnnotationMetadata} of the importing @{@link Configuration} class.
    */
   String[] selectImports(AnnotationMetadata importingClassMetadata);

}
4.2 【springboot-enable-other】编写实现 ImportSelector 接口的类,设置需要产生 Bean 的类全限定名
代码语言:javascript
复制
package com.lijw.springbootenableother.config;

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

public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{"com.lijw.springbootenableother.domain.User", "com.lijw.springbootenableother.domain.Role"};
    }
}

返回的字符串数组 设置需要产生 bean 的类即可。

4.3 【springboot-enable】导入 ImportSelector 实现类,验证两个类的 bean
代码语言:javascript
复制
@SpringBootApplication
@Import(MyImportSelector.class)
public class SpringbootEnableApplication {

    public static void main(String[] args) {
        // 获取IOC容器
        ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);
        // 其他工程
        Object user = context.getBean(User.class);
        System.out.println(user);

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

}

5.【springboot-enable】导入 ImportBeanDefinitionRegistrar 实现类

5.1 【springboot-enable-other】编写实现 ImportBeanDefinitionRegistrar 接口的类,设置需要产生 Bean 的类全限定名
代码语言:javascript
复制
package com.lijw.springbootenableother.config;

import com.lijw.springbootenableother.domain.Role;
import com.lijw.springbootenableother.domain.User;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        // registry 可以用来向 IOC 容器注册类
        // 注册user
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition();
        registry.registerBeanDefinition("user", beanDefinition);

        // 注册role
        registry.registerBeanDefinition("role", BeanDefinitionBuilder.rootBeanDefinition(Role.class).getBeanDefinition());
    }
}
5.2【springboot-enable】导入 ImportBeanDefinitionRegistrar 实现类,并验证生成的 bean
代码语言:javascript
复制
package com.lijw.springbootenable;


import com.lijw.springbootenableother.config.MyImportBeanDefinitionRegistrar;
import com.lijw.springbootenableother.config.MyImportSelector;
import com.lijw.springbootenableother.config.UserConfig;
import com.lijw.springbootenableother.domain.Role;
import com.lijw.springbootenableother.domain.User;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;

@SpringBootApplication
@Import(MyImportBeanDefinitionRegistrar.class)
public class SpringbootEnableApplication {

    public static void main(String[] args) {
        // 获取IOC容器
        ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);
        // 其他工程
        Object user = context.getBean("user");
        System.out.println(user);

        Object role = context.getBean("role");
        System.out.println(role);
    }

}

可以看到也是成功生成了 bean 对象了。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-03-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 海洋的渔夫 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 17-SpringBoot自动配置-@Import详解
    • @Import详解
      • 案例演示
        • 1.【springboot-enable】使用@Import 导入 User 类
        • 2.【springboot-enable】获取 IOC 容器中的 bean 映射 map
        • 3.【springboot-enable】使用@Import 导入 UserConfig 配置类
        • 4.【springboot-enable】导入 ImportSelector 实现类
        • 5.【springboot-enable】导入 ImportBeanDefinitionRegistrar 实现类
    相关产品与服务
    容器服务
    腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档