目录
四、ImportBeanDefinitionRegistrar接口
@Import 导入组件,可以导入一个或多个,当多个的时候用花括号括起来,并用逗号分隔
一、知识点
/*
* 给容器注册组件
* 1)包扫描+容器标注注解,(@Controller/@Service/@Repository)[自己写的类]
* 2)@Bean[导入]第三方里面的组件
* 3) @Import[快速给容器中导入一个组件]
* 1.@Import(要导入的容器中的组件):容器中就会自动注册这个组件,id默认是全类名
* 2.ImportSelector接口:返回需要导入的组件全类名数组(常用)
* 3.ImportBeanDefinitionRegistrar接口:手工注册bean到容器中
*4) 使用Spring提供的 FactoryBean接口(工帮Bean)
* 1.默认获取到的是工厂Bean调用getObject创建的对象
* 2.要获取工厂Bean本身,我们需要给id前面加一个&
* &colorFactoryBean
* */
二、使用@Import导入组件
2.1 知识点
使用@Import导入组件,id默认是组件全类名,如果是导入多个可以用花括号,类之间用逗号隔开
2.2 例子
这个例子是基于《hualinux spring 4.5:@ComponentScan自动扫描》例1的基础上进行操作的,我在此基础上添加几空的类
src-->com.hualinux.beans.Color.java
package com.hualinux.beans;
public class Color {
}
src-->com.hualinux.beans.Red.java
package com.hualinux.beans;
public class Red {
}
src-->com.hualinux.beans.Blue.java
package com.hualinux.beans;
public class Blue {
}
src-->com.hualinux.beans.Green.java
package com.hualinux.beans;
public class Green {
}
conf.MainConfAutoScan.java配置文件修改如下
package conf;
import com.hualinux.beans.Color;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
//我把自动扫描也注解掉了
//@ComponentScan(value = "com.hualinux.beans")
@Configuration
@Import(Color.class)
public class MainConfAutoScan {
}
其它都保持不变,运行com.hualinux.beans.AutoScanMain.java,结果如下:
PS:如果是多个类的话,可以使用花括号
@Configuration @Import({Color.class, Red.class, Blue.class}) public class MainConfAutoScan {
运行如果如下:
三、使用ImportSelector接口(常用)
3.1 介绍
ImportSelector接口:返回需要导入的组件全类名数组,这个功能使用的比较多
3.2 例子
也是在上面的基础上 2.2例子上进行修改
src-->com.hualinux.beans.MyImportSelector.java
package com.hualinux.beans;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
public class MyImportSelector implements ImportSelector {
public String[] selectImports(AnnotationMetadata annotationMetadata) {
//方法不要返回NUll值
//return new String[0];
return new String[]{"com.hualinux.beans.Blue", "com.hualinux.beans.Red"};
}
}
conf.MainConfAutoScan.java配置文件修改为:
@Configuration
@Import({Color.class, MyImportSelector.class})
public class MainConfAutoScan {
}
其它都保持不变,运行com.hualinux.beans.AutoScanMain.java,结果如下:
四、ImportBeanDefinitionRegistrar接口
4.1 功能
ImportBeanDefinitionRegistrar接口:手工注册bean到容器中
4.2 例子
我在3.2 例子的基础上继续操作,使用ImportBeanDefinitionRegistrar做一下判断,如果Red.java和Blue.java同时存在则手工注册一个名为rainBow的Bean
我在这里只要添加多一个类实现ImportBeanDefinitionRegistrar即可
src-->com.hualinux.beans.MyImportBeanDefinitionRegistrar.java
package com.hualinux.beans;
import com.hualinux.beans.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 {
/*
* AnnotationMetadata:当前类的注册信息
* BeanDefinitionRegistry:BeanDefinition注册类
* 把所有需要增加到容器中的Bean;
* BeanDefinitionRegistry.registerBeanDefinition手工注册进来
* */
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
//判断两个注册类是否相同
boolean definiton = beanDefinitionRegistry.containsBeanDefinition("com.hualinux.beans.Red");
boolean definition2 = beanDefinitionRegistry.containsBeanDefinition("com.hualinux.beans.Blue");
//如果找到上面的2人类则注册 rainBow 的Bean
if (definiton && definition2) {
System.out.println("definiton && definition2");
// 指定Bean我定义信:Bean的类型
RootBeanDefinition beanDefinition = new RootBeanDefinition(RainBow.class);
//注册一个Bean,指定bean名
beanDefinitionRegistry.registerBeanDefinition("rainBow", beanDefinition);
}
}
}
在conf.MainConfAutoScan.java配置类用@Import也把这个类当组件导入
@Configuration
//@Import({Color.class, MyImportSelector.class})
@Import({Color.class,MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})
public class MainConfAutoScan {
}
其它都保持不变,运行com.hualinux.beans.AutoScanMain.java,结果如下:
五、使用FactoryBean接口
5.1 介绍
使用Spring提供的 FactoryBean接口(工帮Bean)
1.默认获取到的是工厂Bean调用getObject创建的对象
2.要获取工厂Bean本身,我们需要给id前面加一个&colorFactoryBean
5.2 例子
我就直接建立一个工厂类,再写一个工厂类的bean,获取试下
src-->com.hualinux.beans.ColorFactoryBean.java
package com.hualinux.beans;
import org.springframework.beans.factory.FactoryBean;
public class ColorFactoryBean implements FactoryBean<Color> {
public Color getObject() throws Exception {
System.out.println("ColorFactoryBean...getObject...");
return new Color();
}
public Class<?> getObjectType() {
return Color.class;
}
//是单例?
//true:这个beanj是单实例,在容器中保存一份
//false:多实例,每次获取都会创建一个新的bean
public boolean isSingleton() {
return false;
//return true;
}
}
conf.MainConfAutoScan.java配置文件修改如下:
@Configuration
//@Import({Color.class, MyImportSelector.class})
@Import({Color.class,MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})
public class MainConfAutoScan {
@Bean
public ColorFactoryBean colorFactoryBean() {
return new ColorFactoryBean();
}
}
com.hualinux.beans.AutoScanMain.java代码修改如下:
package com.hualinux.beans;
import conf.MainConfAutoScan;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class AutoScanMain {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx=new AnnotationConfigApplicationContext(MainConfAutoScan.class);
String[] beanDefinitionNames = ctx.getBeanDefinitionNames();
for (String name: beanDefinitionNames){
System.out.println(name);
}
Object colorFactoryBean = ctx.getBean("colorFactoryBean");
System.out.println("Bean的类型为:"+colorFactoryBean.getClass());
//拿到它本身类
Object colorFactoryBean2 = ctx.getBean("&colorFactoryBean");
System.out.println("Bean2的类型为:"+colorFactoryBean2.getClass());
}
}
运行上面的com.hualinux.beans.AutoScanMain.java结果如下: