【Spring(六)】@Import 注解使用

本文详细解析Spring框架中的@Import注解,探讨其如何用于自动注册大量bean,简化配置过程。通过实例展示了@Import在@Configuration类及ImportSelector、ImportBeanDefinitionRegistrar接口中的运用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

看下注解定义:
 

 * Indicates one or more {@link Configuration @Configuration} classes to import.
 *
 * <p>Provides functionality equivalent to the {@code <import/>} element in Spring XML.
 * Only supported for classes annotated with {@code @Configuration} or declaring at least
 * one {@link Bean @Bean} method, as well as {@link ImportSelector} and
 * {@link ImportBeanDefinitionRegistrar} implementations.

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {

	/**
	 * The @{@link Configuration}, {@link ImportSelector} and/or
	 * {@link ImportBeanDefinitionRegistrar} classes to import.
	 */
	Class<?>[] value();
}

注解的第一行写的很明白,@Import表明需要引入多个@Configuration注解配置。这就是@Import的用处。

使用条件,指的是Import的属性,即引入的class:必须被@Configuration标注或者至少有一个@Bean注解或者实现了ImportSelector/ImportBeanDefinitionRegistar接口。

我们可能在什么情况下使用这个注解?

自动注册一堆bean。我们可以按业务或者模块划分很多bean,就拿spring来说,基于注解的容器需要一堆的processor,springmvc业务要一堆requestmapping的bean,那么我们可以为每一个模块或者类别搞一个java的config类或者ImportSelector/ImportBeanDefinitionRegistar接口的实现,在需要的时候,在我们的java配置类上使用@Import导入即可。

springmvc的@EnableWebMvc就是一个很好的例子:

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

如果要 启用springmvc,那么就要引入相关的bean,我们直接在应用的java配置类上使用@EnableWebMvc即可,相关的bean定义在DelegatingWebMvcConfiguration的父类中通过@Bean的方式定义了。

下面具体看下@Import的使用。

@Bean方式引入:

beans:

public class Player2 {

    private CD cd;

    public void play(){
        cd.sound();
    }

    public void setCD(CD cd){
        this.cd = cd;
    }
}
public class CD2 implements CD {

    public void sound() {
        System.out.println("bababa");
    }
}

定义几个@Bean的java配置类:

public class Bean1 {
    @Bean(name = "cd2")
    public CD2 getCD2(){
        return new CD2();
    }
}
public class Bean2 {
    @Bean(name = "player2")
    public Player2 getPlayer2(CD cd){
        Player2 player2 = new Player2();
        player2.setCD(cd);
        return player2;
    }
}

定义配置类:

@Configuration
@Import({Bean1.class, Bean2.class})
public class JavaConfig {

}

使用:

public class Main {
    public static void main(String args[]) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(JavaConfig.class);
        Player2 player2 = (Player2) applicationContext.getBean("player2");
        player2.play();
    }
}

 

ImportSelector:

public class TestSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        System.out.println(importingClassMetadata.getAnnotationTypes());
        return new String[]{Bean1.class.getName(), Bean2.class.getName()};
    }
}

这个方法返回需要引入的配置类的类名。入参AnnotationMetadata是被该注解标注的类的注解信息,可以拿到其他标注注解。

这个也是ImportSelector的牛逼之处吧,虽然这个例子并没有体现,与之前的方法一致。但是如果我想拿到其他注解做一些特殊处理,或者对配置类做一些处理,ImportSelector是可以支持的。

具体可以参考下这个例子:https://blog.youkuaiyun.com/elim168/article/details/88131614

 

ImportBeanDefinitionRegistrar:

public class TestRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(CD2.class);
        registry.registerBeanDefinition("cd2", builder.getBeanDefinition());

        BeanDefinitionBuilder builder1 = BeanDefinitionBuilder.rootBeanDefinition(Player2.class);
        registry.registerBeanDefinition("player2", builder1.getBeanDefinition());
    }
}

另外需要在Player2类的cd属性上加上@Autowired,因为没有@Bean注解做装配了。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值