07-组件注册-@Import、@ImportSelector、@ImportBeanDefinitionRegistrar及FactoryBean工厂方式,给容器中导入一个组件

目录

1、@Import(要导入容器中的组件)方式,容器中就会自动注册这个组件,id默认为组件全类名。

2、@ImportSelector方式:返回需要导入的组件的全类名数组

3、@ImportBeanDefinitionRegistrar方式:手工注册bean到容器中。

4、使用Spring提供的FactoryBean(工厂Bean)



  • 包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)【局限于自己创建的类】 前面已经讲解
  • @Bean【导入的第三方包里面的组件】   前面已经讲解
  • @Import【快速给容器中导入一个第三方组件】 

      -@Import(要导入容器中的组件)方式,容器中就会自动注册这个组件,id默认为组件全类名。

      -@ImportSelector方式:返回需要导入的组件的全类名数组

      -@ImportBeanDefinitionRegistrar方式:手工注册bean到容器中

  • 使用Spring提供的FactoryBean(工厂Bean)

      

今天我们说下@Import方式

1、@Import(要导入容器中的组件)方式,容器中就会自动注册这个组件,id默认为组件全类名。

为了测试方便,我们自己创建类Color 和 Red类,通过import 导入进来。

package com.spring.bean;

public class Color {

}

package com.spring.bean;
public class Red {
}

配置类中引入组件

@Configuration
@Import({Color.class, Red.class})
public class MainConfig2 {

}

测试方法:

public class IocTest {
    AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);

    @Test
    public void test04(){
        printBeans();
    }

    private void printBeans(){
        String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();

        for(String name:beanDefinitionNames){
            System.out.println(name);
        }
    }
}

输出结果:

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig2
com.spring.bean.Color
com.spring.bean.Red

2、@ImportSelector方式:返回需要导入的组件的全类名数组

创建两个类,通过这种方式引入

package com.spring.bean;

public class Book {
}

package com.spring.bean;

public class User {
}

创建自定义Selector,实现ImportSelector接口,返回值中加入User、Book的全类名

package com.spring.Condition;

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

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

    /**
     *  返回值,就是导入到容器中的组件的全类名
     * @param importingClassMetadata  当前标注@Import注解的类的所有注解信息
     * @return
     */
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {

        return new String[]{"com.spring.bean.User","com.spring.bean.Book"};
    }

}

配置类中@Import MyImportSelector

@Configuration
@Import({Color.class, Red.class, MyImportSelector.class})
public class MainConfig2 {
}

测试输出容器中的组件

public class IocTest {
    AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);

    @Test
    public void test04(){
        printBeans();
    }


    private void printBeans(){
        String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();

        for(String name:beanDefinitionNames){
            System.out.println(name);
        }
    }
}

结果为:

三月 29, 2020 12:28:40 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@37d31475: startup date [Sun Mar 29 00:28:40 CST 2020]; root of context hierarchy
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig2
com.spring.bean.Color
com.spring.bean.Red
com.spring.bean.User
com.spring.bean.Book

3、@ImportBeanDefinitionRegistrar方式:手工注册bean到容器中。

创建类Car,通过这种方式方式引入(测试方便,未引入第三方组件)

package com.spring.bean;

public class Car {
}

创建接口ImportBeanDefinitionRegistrar 的实现类 MyImportBeanDefinitionRegistrar

package com.spring.Condition;

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,BeanDefinitionRegistry.registerBeanDefinition  手工注册。
     */
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        boolean b = registry.containsBeanDefinition("com.spring.bean.Book");
        boolean b1 = registry.containsBeanDefinition("com.spring.bean.User");

        //如果容器中有 Book 和User组件,就将 Car组件注册到容器中
        if(b && b1){
            registry.registerBeanDefinition("car",new RootBeanDefinition("com.spring.bean.Car"));
        }
    }
}

配置类中@Import(MyImportBeanDefinitionRegistrar.class)

@Configuration
@Import({Color.class, Red.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class MainConfig2 {

}

执行打印输出容器中的组件,结果为

三月 29, 2020 12:46:37 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@37d31475: startup date [Sun Mar 29 00:46:37 CST 2020]; root of context hierarchy
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig2
com.spring.bean.Color
com.spring.bean.Red
com.spring.bean.User
com.spring.bean.Book
car

car 对象已经注册入ioc容器中!

4、使用Spring提供的FactoryBean(工厂Bean)

首先实现FactoryBean 接口

package com.spring.bean;

import org.springframework.beans.factory.FactoryBean;

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

    //返回Color对象,这个对象会添加容器中
    public Color getObject() throws Exception {
        System.out.println("ColorFactoryBean...getObject....");
        return new Color();
    }

    public Class<?> getObjectType() {
        return Color.class;
    }

    /**
     * 是否单实例
     * true 单实例,在容器中存在一份
     * false 多实例,每次获取都会创建一个新bean
     * @return
     */
    public boolean isSingleton() {
        return true;
    }
}
package com.spring.bean;

public class Color {

}

在配置类中加入方法,通过工厂类获取实例。

@Configuration
public class MainConfig2 {

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

测试一下,看容器中注册了什么对象实例

    @Test
    public void testImport(){
        printBeans();

        //工厂Bean 获取的是调用getObject创建的对象
        Object colorFactoryBean = annotationConfigApplicationContext.getBean("colorFactoryBean");
        Object colorFactoryBean2 = annotationConfigApplicationContext.getBean("colorFactoryBean");
        System.out.println("bean 类型:"+colorFactoryBean.getClass());
        System.out.println(colorFactoryBean==colorFactoryBean2);
    }

  private void printBeans(){
        String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();

        for(String name:beanDefinitionNames){
            System.out.println(name);
        }
    }

结果返回:

信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@37d31475: startup date [Sun Mar 29 08:20:03 CST 2020]; root of context hierarchy
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig2
colorFactoryBean
ColorFactoryBean...getObject....
bean 类型:class com.spring.bean.Color
true

可以看出注册组件id 为:colorFactoryBean  类型却是:com.spring.bean.Color

并且两次创建是同一实例(单例)

如果改变方法:isSingleton() 的返回值为false

   public boolean isSingleton() {
        return false;
    }

结果可以看出创建两个不同对象实例,创建了两次。

ColorFactoryBean...getObject....
ColorFactoryBean...getObject....
bean 类型:class com.spring.bean.Color
false

如果需要获取工厂bean本身,只需要id前加入&符号

Object colorFactoryBean3 = annotationConfigApplicationContext.getBean("&colorFactoryBean");
        System.out.println(colorFactoryBean3.getClass());

返回结果为

class com.spring.bean.ColorFactoryBean

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值