【SpringBoot_ANNOTATIONS】组件注册 07 @Import 给容器快速导入一个组件

组件注册 07 @Import 给容器快速导入一个组件

给容器注册组件:

  1. 包扫描 + 组件标注注解(@Controller @Service @Repository @Component),局限于自己写的
  2. @Bean(可导入第三方包里的组件)
  3. @Import(快速给容器中导入组件)
    1. @Import([要导入容器中的组件]):容器中就会自动注册这个组件,id默认为全类名 @Import(Color.class) @Import({Color.class,Red.class})
    2. 实现ImportSelector接口:返回需要导入的组件的全类名数组
    3. 实现ImportBeanDefinitionRegistrar接口:手动注册bean到容器中
  4. 使用Spring提供的FactoryBean工厂

配置类 MainConfig3.class

测试

    @Test
    void importTest(){
        //配置类测试
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig3.class);
        System.out.println("容器创建完毕");
        System.out.println("准备获取bean...");
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (String name:beanDefinitionNames){
            System.out.println(name);
        }
    }

ImportSelector 测试

Color.java

package com.example.annotations.bean;

public class Color {
}

Red.java

package com.example.annotations.bean;

public class Red {
}

MyImportSelector.java

package com.example.annotations.importselector;

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

/**
 * 自定义逻辑返回需要导入的组件
 */
public class MyImportSelector implements ImportSelector {

    // 返回值:导入到容器中的组件 (全类名)
    // AnnotationMetadata:当前标注@Import注解的类的所有注解信息
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        // 不能返回 null  可以是空数组
        return new String[]{"com.example.annotations.bean.Color","com.example.annotations.bean.Red"};
    }
}

运行结果:
在这里插入图片描述

实现ImportBeanDefinitionRegistrar接口

MyImportBeanDefinitionRegistrar.class

package com.example.annotations.importselector;

import com.example.annotations.bean.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;

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    /**
     *
     * @param importingClassMetadata 当前类的注解信息
     * @param registry               BeanDefinition的注册类  负责将bean添加进容器
     */
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        // 指定bean定义信息(Bean的类型 Bean的作用域 ...)
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(RainBow.class);

        // 注册:指定bean名
        if (!registry.containsBeanDefinition("rainbow")){
            System.out.println(" start create 'rainbow' ...");

            registry.registerBeanDefinition("rainbow",rootBeanDefinition);
        }else {
            System.out.println("'rainbow' already exists ");
        }
    }
}

运行结果
在这里插入图片描述

使用FatoryBean

普通bean

将bean导入到容器后,容器会调用其无参构造器,默认创建一个对象注册在容器中

FactoryBean

  1. 是一个接口
  2. 整合第三方框架的时候用的多
  3. 默认获取的是工厂bean调用getObject创建的对象
  4. 要获取工厂bean本身,需要给id前加一个 &
需要实现方法

getObject()
getObjectType()

isSingleton() :默认是true 单实例

实例测试

ColorFactoryBean.java

package com.example.annotations.bean;

import org.springframework.beans.factory.FactoryBean;

/**
 * 创建一个Spring定义的FactoryBean
 */
public class ColorFactoryBean implements FactoryBean<Color> {


    /**
     * 返回分Color对象会被添加到容器中
     * @return Color
     * @throws Exception
     */
    @Override
    public Color getObject() throws Exception {
        return new Color();
    }

    /**
     *
     * @return
     */
    @Override
    public Class<?> getObjectType() {
        return Color.class;
    }

    /**
     * true: 单实例 在容器中保存一份
     * false:多实例 每获取一次就会创建一个新bean
     * @return
     */
    @Override
    public boolean isSingleton() {
        return true;
    }
}

MainConfig2.java

@Configuration
public class MainConfig2 {
    @Bean
    public ColorFactoryBean colorFactoryBean(){
        return new ColorFactoryBean();
    }
}

测试

    @Test
    void factoryBeanTest(){
        //配置类测试
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
        System.out.println("容器创建完毕");
        System.out.println("准备获取bean...");
        Object bean1 = applicationContext.getBean("colorFactoryBean");//Color.class
        Object bean2 = applicationContext.getBean("colorFactoryBean");//Color.class
        System.out.println("bean1 == bean2? => " + (bean1 == bean2));
    }

测试结果
true 运行结果
现将ColorFactoryBean.java中的isSingleton改为false,再次运行
false 运行结果
查看获取的类型

    @Test
    void factoryBeanTest(){
        //配置类测试
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
        System.out.println("容器创建完毕");
        System.out.println("准备获取bean...");
        Object bean1 = applicationContext.getBean("colorFactoryBean");//Color.class  获取的是工厂bean调用 
        Object bean2 = applicationContext.getBean("&colorFactoryBean");//ColorFactoryBean.class
        System.out.println("bean1 == bean2? => " + (bean1 == bean2));
        System.out.println("bean1 " + bean1.getClass());
        System.out.println("bean2 " + bean2.getClass());
    }

类型测试

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值