6-组件注册-@Import

本文知识点来源于尚硅谷,感谢尚硅谷为广大学子提供的优质教育资源,感谢各位老师热情指导,本文仅作为学习笔记使用,记录学习心得,如有不适,请联系作者。

给容器注册组件的方式:

  1. 包扫描+标注注解 @Controller @Service @Repository @Component 适用于我们自己写的类。
  2. @Bean,适用于导入第三方包里面的组件。
  3. @Import ,快速给容器中导入一个组件
    1)@Import({Color.class,Red.class})快速给容器导入组件 id默认为全类名 如:cn.tedu.bean.Color
    2)ImportSelector 返回值就是导入到容器的组件全类名数组 不能为null
    3)ImportBeanDefinitionRegistrar
  4. 使用Spring提供的FactoryBean(工厂bean)

一、@Import 给容器中快速导入一个组件

@Import 导入组件,参数为数组,id默认为全类名
配置类如下:

@Configuration //告诉Spring这是一个配置类
@Import({Color.class})//导入组件,参数为数组,id默认为全类名
public class MainConfig2 {
	@Bean//默认单实例Bean
	public Person person() {
		return new Person("李四",18,"男");
	}
}

新增Color类:

public class Color {
	
}

测试方法如下:

	@Test
	public void test_Import() {
		ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
		String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
		for (String name : beanDefinitionNames) {
			System.out.println(name);
		}		
	}

输出:

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig2
com.tedu.bean.Color
person

二、@Import @Import-使用ImportSelector

ImportSelector 返回值就是导入到容器的组件全类名数组 不能为null
新增测试Bean:

public class Blue {

}
public class Yellow {

}

新增自定义选择器:

import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
/**
 * 自定义逻辑返回需要导入的组件
 * @author Administrator
 *
 */
public class MyImportSelect implements ImportSelector{
	
	/**
	 * importingClassMetadata 
	 *  	当前标注@Import注解类的所有注解信息
	 * 
	 * @return 
	 * 		返回值为导入到容器的组件全类名,切记不能返回Null,会报空指针
	 */
	@Override
	public String[] selectImports(AnnotationMetadata importingClassMetadata) {		
		return new String[] {"com.tedu.bean.Blue","com.tedu.bean.Yellow"};
	}
}

配置类如下,@Import中新增MyImportSelect.class:

@Configuration //告诉Spring这是一个配置类
@Import({Color.class,MyImportSelect.class})//导入组件,参数为数组,id默认为全类名
public class MainConfig2 {
	@Bean//默认单实例Bean
	public Person person() {
		return new Person("李四",18,"男");
	}
}

测试类不变,执行并输出:

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig2
com.tedu.bean.Color
com.tedu.bean.Blue
com.tedu.bean.Yellow
person

三、@Import 使用ImportBeanDefinitionRegistrar

新增测试Bean:

public class RainBow {
	
}

新增自定义注册类实现ImportBeanDefinitionRegistrar接口:

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;

import com.tedu.bean.RainBow;
/**
 * 自定义注册类
 */
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar{
	
	/**
	 * importingClassMetadata
	 * 		当前类的注解信息
	 * registry
	 * 		BeanDefinition注册类,把所有需要添加到容器中的bean
	 * 		调用BeanDefinitionRegistry.registerBeanDefinition(beanName, beanDefinition)手动注册进来。
	 * 
	 */
	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		//这里是bean id
		boolean red = registry.containsBeanDefinition("person");
		boolean yellow = registry.containsBeanDefinition("com.tedu.bean.Yellow");
		if (red || yellow) {
			//指定Bean的定义信息(类型,作用域等)
			RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(RainBow.class);
			//指定bean id为RainBow1
			registry.registerBeanDefinition("RainBow1", rootBeanDefinition);			
		}
	}
}

配置类@Import中加入我们的自定义注册类

@Configuration //告诉Spring这是一个配置类
@Import({Color.class,MyImportSelect.class,MyImportBeanDefinitionRegistrar.class})//导入组件,参数为数组,id默认为全类名
public class MainConfig2 {
}

测试类不变输出:

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig2
com.tedu.bean.Color
com.tedu.bean.Blue
com.tedu.bean.Yellow
person
RainBow1

四、使用FactoryBean注册组件

新增自定义工厂bean实现FactoryBean接口

import org.springframework.beans.factory.FactoryBean;

import com.tedu.bean.Color;

public class ColorFacatoryBean implements FactoryBean<Color>{
	
	/**
	 * 返回对象会添加到容器
	 */
	@Override
	public Color getObject() throws Exception {
		return new Color();
	}
	
	/**
	 * 返回Bean类型
	 */
	@Override
	public Class<?> getObjectType() {
		return Color.class;
	}
	
	/**
	 * 是否单例 
	 * 		true 是
	 */
	@Override
	public boolean isSingleton() {
		return true;
	}
}

配置类:

/**
 * 配置类==配置文件xml
 * @author Administrator
 *
 */
@Configuration //告诉Spring这是一个配置类
public class MainConfig2 {
	@Bean()
	public ColorFacatoryBean colorFacatoryBean() {
		return new ColorFacatoryBean();
	}
	
}

测试方法:

	@Test
	public void test_FactoryBean() {
		ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
		String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
		for (String name : beanDefinitionNames) {
			System.out.println("javaBean名:" + name);
		}
		System.out.println("=========获取Bean的类型默认为===========");
		Object bean = applicationContext.getBean("colorFacatoryBean");
		//获取的是调用getObject()返回的对象
		System.out.println("bean的类型:" + bean.getClass());
		System.out.println("===========判断是否是单例=============");
		//调用多次,看是否为单例
		Object bean2 = applicationContext.getBean("colorFacatoryBean");
		System.out.println(bean == bean2);
		System.out.println("=============获取工厂bean本身类型=============");
		//如果我只想获取工厂bean本身类型,需要在id前加一个&符
		Object bean3 = applicationContext.getBean("&colorFacatoryBean");
		System.out.println(bean3);
	}	

输出:

javaBean名:org.springframework.context.annotation.internalConfigurationAnnotationProcessor
javaBean名:org.springframework.context.annotation.internalAutowiredAnnotationProcessor
javaBean名:org.springframework.context.annotation.internalCommonAnnotationProcessor
javaBean名:org.springframework.context.event.internalEventListenerProcessor
javaBean名:org.springframework.context.event.internalEventListenerFactory
javaBean名:mainConfig2
javaBean名:colorFacatoryBean
=========获取Bean的类型默认为===========
bean的类型:class com.tedu.bean.Color
===========判断是否是单例=============
true
=============获取工厂bean本身类型=============
com.tedu.config.ColorFacatoryBean@7995092a

我们可以看到定义的javaBean名称中虽然有colorFacatoryBean,但是通过getBean()获取的Bean类型却是com.tedu.bean.Color类型,这说明getBean获取的是调用getObject()返回的对象,并且是我们是我们设置的单例,如果想拿到工厂Bean本身类型需要在id前加“&”符号。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值