spring注解@Import、ImportSelector、ImportBeanDefinitionRegistrar向IOC容器中导入组建


 * 在容器中注册组建
 *      1:包扫描:带用注解的组建(@Controller、@Service、@Repotitory...)
 *      2:bean注解导入组建【导入第三方包里的组建】
 *      3:@Import快速向容器中导入组建
 *          1.@Import(需要导入的组建);容器中会自动注册组建,默认id是全类名
 *          2.ImportSelector返回需要导入的组建全类名数组,不可以自定义组建id,全类名
 *          3.ImportBeanDefinitionRegistrar:手动注册bean到容器中,可以自定义组建的id
 *      4:自己定义一个类实现FactoryBean接口,实现其方法,指定要注册到容器中的bean

下面是ImportSelector的用法:

在@Import注解中加入实现了Selector接口的类

具体的解释和注意事项写在了代码中

/**
 * @Import注解导入的组建id默认是全类名
 */
@Import(value = {Color.class,Red.class,MyImportSeletor.class,MyImportBeanDefinitionRegistrar.class})
@Configuration
//将conditional注解放在类上,若不满足条件,则类中所有的bean都不会被注册到IOC容器中
//@Conditional({WindowCondition.class})
public class MainConfig2 {

    //这种方法将ImportSelector类注入到容器中是行不通的,它返回的数组中的类并不会被注册到容器中
    /*@Bean
    public MyImportSeletor seletor(){
        return new MyImportSeletor();
    }*/
MyImportSeletor.class
package com.annotation.ImportSeletor;

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

import java.util.Set;

//实现spring的ImportSelector接口,重写selectImports方法,方法的返回值是一个String数组,数组中包含的全类名会被注册到容器中
//容器中最终注册的组建是返回的全类名,而当前的MyImportSeletor不会被导入到容器中
public class MyImportSeletor implements ImportSelector {

    //AnnotationMetadata:当前标注了@Import注解的类的所有注解信息
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        //获取当前标注了@Import的类的所有注全类名
        Set<String> annotationTypes = importingClassMetadata.getAnnotationTypes();
        for (String annotationType : annotationTypes) {
            System.out.println(annotationType);
        }
        String[] strs = {"com.annotation.entities.Blue","com.annotation.entities.Yellow"};
        //这里可以返回一个空数组,但是不要返回null,否则在spring底层会获取数组的长度,返回null程序会报空指针异常
        return strs;
    }
}

下面是ImportBeanDefinitionRegistrar的用法:

当容器中包含Yellow和Red时,向容器中注册RainBox组建

MyImportBeanDefinitionRegistrar.class
package com.annotation.importannotation;

import org.springframework.beans.factory.config.BeanDefinition;
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;

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    /**
     * AnnotationMetadata:当前Import注解所在类的注解信息
     * BeanDefinitionRegistry
     */
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        System.out.println("当前容器中定义的bean的数量" + registry.getBeanDefinitionCount());
        System.out.println("根据beanName获取容器中的bean" + registry.getBeanDefinition("person"));
        System.out.println("获取容器中所有定义的bean的名字" + registry.getBeanDefinitionNames());
        System.out.println("判断容器中是否有Blue的定义" + registry.containsBeanDefinition("com.annotation.entities.Blue"));
        boolean b = registry.containsBeanDefinition("com.annotation.entities.Yellow");
        boolean b1 = registry.containsBeanDefinition("com.annotation.entities.Red");
        if (b && b1){
            BeanDefinition beanDefinition = new RootBeanDefinition("com.annotation.entities.RainBow");
            registry.registerBeanDefinition("rainBow",beanDefinition);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_36722039/article/details/81589405