本博客demo源码地址
https://github.com/suchahaerkang/spring-annotation.git
下面我们就来学习一下下面两种方式注册组件
这种方式是默认方式,可以将第三方组件快速注册到容器中,在容器中的id默认为全类名
首先我们创建一个Red类当作第三方组件
/**
* @description:
* @author: sukang
* @date: 2020-03-05 15:18
*/
public class Red {
}
测试用例
@Test
public void test05(){
//创建容器
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
//获取IOC容器中的所有组件名
String[] beanNames = applicationContext.getBeanDefinitionNames();
for (String name :beanNames) {
System.out.println(name);
}
}
ImportSelector 是spring提供的一个接口,实现这个接口的selectImports()方法,我们可以自定义返回需要注册的组件的全类名,我们自定义一个实现ImportSelector 接口的类,将新创建的Blue和Yellow类的全类名封装成为一个数组返回
/**
* @description:
* @author: sukang
* @date: 2020-03-05 15:44
*/
public class MyImportSelector implements ImportSelector {
/**
* @description:
* @param importingClassMetadata 当前注解@Import标注的类上面的全部注解信息
* @return: java.lang.String[]
* @author: sukang
* @date: 2020/3/5 15:45
*/
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
String[] str = new String[]{"com.wolfx.bean.Blue","com.wolfx.bean.Yellow"};
return str;
}
}
@Test
public void test05(){
//创建容器
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
//获取IOC容器中的所有组件名
String[] beanNames = applicationContext.getBeanDefinitionNames();
for (String name :beanNames) {
System.out.println(name);
}
}
运行结果
这种方式注册的组件在容器中的id也是全类名,这种方式在springboot中用到的比较多,理解这种方式有助于我们理解springboot里面相关的知识
ImportBeanDefinitionRegistrar也是spring提供的一个接口,如果实现这个接口的registerBeanDefinitions()方法,我们可以利用这个方法的一个参数BeanDefinitionRegistry进行手动注册组件到容器中去,我们写一个实现类
/**
* @description:
* @param importingClassMetadata 当前注解@Import标注的类的所有注解信息
* @param registry 组件信息注册中心,通过它可以手动注册组件
* @return: void
* @author: sukang
* @date: 2020/3/5 16:04
*/
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//判断容器中是否有Blue和Yellow的组件
Boolean boolean1 = registry.containsBeanDefinition("com.wolfx.bean.Blue");
Boolean boolean2 = registry.containsBeanDefinition("com.wolfx.bean.Yellow");
if(boolean1 && boolean2){
//定义一个RainBow组件信息,这里也可以指定一个组件的作用域
BeanDefinition beanDefinition = new RootBeanDefinition(RainBow.class);
//将RainBow组件信息注册到容器中去,在容器中的id为rainBow
registry.registerBeanDefinition("rainBow", beanDefinition);
}
}
@Test
public void test05(){
//创建容器
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
//获取IOC容器中的所有组件名
String[] beanNames = applicationContext.getBeanDefinitionNames();
for (String name :beanNames) {
System.out.println(name);
}
}
FactoryBean是Spring提供的特殊bean接口,实现它的类要重写getObject(),getObjectType()方法。其他三种组件注册方法,都是将组件注册到容器中去,然后通过调用组件的构造函数创建的实例,而FactoryBean这种方式是通过调用getObject()方法来创建组件。我们自定义一个实现FactoryBean接口的类
/**
* @description:
* @author: sukang
* @date: 2020-03-05 16:26
*/
public class WhiteFactoryBean implements FactoryBean<White> {
//FactoryBean 是通过这个方法将组件添加到容器中的
public White getObject() throws Exception {
return new White();
}
public Class<?> getObjectType() {
return White.class;
}
//true:为单实例
//false:为多实例
public boolean isSingleton(){
return true;
}
}
在配置类中配置将WhiteFactoryBean注册到容器中
@Bean
public WhiteFactoryBean whiteFactoryBean(){
return new WhiteFactoryBean();
}
测试用例
@Test
public void test06() throws Exception {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
System.out.println(applicationContext.getBean("whiteFactoryBean"));
}
运行结果
通过运行结果我们可以看到从容器中获取id为whiteFactoryBean的对象并不是WhiteFactoryBean组件的实例,而是White组件的实例,那么我们怎么才能获取到WhiteFactoryBean类的实例呢?通过看源码我们可知需要在id前面加上一个&
测试用例
@Test
public void test06() throws Exception {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
System.out.println(applicationContext.getBean("&whiteFactoryBean"));
}