在@Import注解中使用ImportBeanDefinitionRegistrar向容器中注册bean

1.ImportBeanDefinitionRegistrar接口的简要介绍

public interface ImportBeanDefinitionRegistrar {

    default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry,
            BeanNameGenerator importBeanNameGenerator) {

        registerBeanDefinitions(importingClassMetadata, registry);
    }

    
    default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    }
}

ImportBeanDefinitionRegistrar本质上是一个接口。在ImportBeanDefinitionRegistrar接口中,有registerBeanDefinitions()方法,通过该方法,我们可以向Spring容器中注册bean实例。

Spring官方在动态注册bean时,大部分套路其实是使用ImportBeanDefinitionRegistrar接口。

所有实现了该接口的类都会被ConfigurationClassPostProcessor处理,ConfigurationClassPostProcessor实现了BeanFactoryPostProcessor接口,所以ImportBeanDefinitionRegistrar中动态注册的bean是优先于依赖其的bean初始化的,也能被aop、validator等机制处理。

2.使用方法

ImportBeanDefinitionRegistrar需要配合@Configuration和@Import这俩注解,其中,@Configuration注解定义Java格式的Spring配置文件,@Import注解导入实现了ImportBeanDefinitionRegistrar接口的类。

创建一个MyImportBeanDefinitionRegistrar类,去实现ImportBeanDefinitionRegistrar接口,如下所示。

package com.tianxia.springannotation.config.configImport;

import com.tianxia.springannotation.entity.RainBow;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

/**
 * ImportBeanDefinitionRegistrar接口实例
 * @author liqb
 * @date 2023-04-24 10:45
 **/
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    /**
     * 手动注册所有需要添加到容器中的bean
     * @author liqb
     * @date 2023-04-24 10:58
     * @param annotationMetadata 当前类的注解信息
     * @param registry BeanDefinition注册类
     */
    @Override
    public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) {
        boolean definition = registry.containsBeanDefinition("com.tianxia.springannotation.entity.Red");
        boolean definition2 = registry.containsBeanDefinition("com.tianxia.springannotation.entity.Bule");
        if (definition && definition2) {
            // 指定bean的定义信息,包括bean的类型、作用域等等
            // RootBeanDefinition是BeanDefinition接口的一个实现类
            RootBeanDefinition beanDefinition = new RootBeanDefinition(RainBow.class); // bean的定义信息
            // 注册一个bean,并且指定bean的名称
            registry.registerBeanDefinition("rainBow", beanDefinition);
        }
    }
}

在配置类上的@Import注解中,添加MyImportBeanDefinitionRegistrar类,如下所示。

package com.tianxia.springannotation.config;

import com.tianxia.springannotation.config.configEntity.CustomerScope;
import com.tianxia.springannotation.config.configImport.MyImportBeanDefinitionRegistrar;
import com.tianxia.springannotation.config.configImport.MyImportSelector;
import com.tianxia.springannotation.entity.Color;
import com.tianxia.springannotation.entity.Person;
import com.tianxia.springannotation.entity.Red;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Scope;

/**
 * 配置类
 * @author liqb
 * @date 2023-04-23 10:45
 **/
@Configuration
// @Import快速地导入组件,id默认是组件的全类名
@Import({Color.class, Red.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class MainConfig03 {

    /**
     * 创建person实例
     * @author liqb
     * @date 2023-04-23 09:46
     * @return
     */
    @Bean("person03")
    @Scope(CustomerScope.CUSTOMER_SCOPE)
    public Person person() {
        System.out.println("给容器中添加咱们这个Person对象...");
        return new Person("liqb", 24);
    }
}

创建一个RainBow类,作为测试ImportBeanDefinitionRegistrar接口的bean来使用,如下所示

package com.tianxia.springannotation.entity;

/**
 * 彩虹类
 * @author liqb
 * @date 2023-04-24 11:02
 **/
public class RainBow {
}

调用测试方法,输出的结果信息如下所示:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值