《读spring源码》13实现ImportBeanDefinitionRegistrar接口可以手动添加组件到IOC容器

package com.enjoy.cap6;

import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

public class TTTImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    /**
     *
     * @param importingClassMetadata  当前类的注解信息
     * @param registry                 注册类  把所有需要添加到容器中的bean加入
     * @param importBeanNameGenerator
     */
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry,
                                         BeanNameGenerator importBeanNameGenerator) {

        registerBeanDefinitions(importingClassMetadata, registry);
    }

    /**
     * 检查  容器中有没有注册 Dog
     *
     * @param importingClassMetadata
     * @param registry
     */
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        boolean b1 = registry.containsBeanDefinition("com.enjoy.cap6.Dog");
        boolean b2 = registry.containsBeanDefinition("com.enjoy.cap6.Cat");
        //如果dog和cat都在容器里面   那么创建Pig 加入到容器
        //对于我们要注册的bean,给bean进行封装
        if(b1 && b2){
            RootBeanDefinition pigBeanDefinition = new RootBeanDefinition(Pig.class);//需要一个bean的定义信息,源代码注册bean的时候都是通过这种新是进行封装然后放入容器中
            registry.registerBeanDefinition("pig",pigBeanDefinition);
        }
    }
}

package com.enjoy.cap6;


import com.enjoy.cap1.Person;
import com.enjoy.cap5.LinCodition;
import com.enjoy.cap5.WinCodition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Import(value = {Dog.class,Cat.class,TTTTImportSelector.class,TTTImportBeanDefinitionRegistrar.class})
public class MainConfig {

    /**
     * 1、@Bean   【导入第三方的类或包的组件】,比如Person为第三方的类,需要我们IOC使用时
     * 2、包扫描+组件的标注注解(@ComponentScan:@Controller,@Service,@Repository,@Componet)一般针对自己写的类
     * 3、@Import:【快速给容器导入一个组件】注意@Bean有点简单
     *              1)@Import(要导入到容器中的组件):容器会自动注册这个组件,bean的id为全类名
     *              2)ImportSelector:是一个接口,返回需要导入到容器的组件的全类名数组。
     *              3)ImportBeanDefinitionRegistrar:模块化管理,可以手动添加组件到IOC容器,所有Bean的注册可以使用BeanDifinitionRegistry
     *              写TTTImportBeanDefinitionRegistrar实现registerBeanDefinitions接口即可
     *
     * 容器启动时初始化person的bean实例
     *
     * @return
     */
    @Bean("person")
    public Person zhangsan(){
        System.out.println("给我们的容器中添加张三");
        return new Person("张三",22);
    }


}


package test;

import com.enjoy.cap6.MainConfig;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * FactoryBean 和 BeanFactorty 有什么区别?
 *
 * FactoryBean :可以把我们的JAVA实例通过FactoryBean注入到容器中
 *
 * BeanFactorty:从我们的容器中获取实例化后的bean
 *
 */
public class MainTEwst6 {


    @Test

    public void sss(){
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
        String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();
        for(String name :beanDefinitionNames){
            System.out.println(name);
        }
    }
}

在这里插入图片描述

注册bean到容器中源码分析:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

发布了434 篇原创文章 · 获赞 58 · 访问量 31万+

猜你喜欢

转载自blog.csdn.net/ppwwp/article/details/103329027