@Import
import用法1
- 这是一种比较简单的向ioc容器导入组件的方法 在配置类上写上需要导入的类即可, 注意这样使用Color需要是无参构造
@Configuration
@Import(Color.class)
public class ImportConfig {
}
- 测试
@Test
void testImport() {
AnnotationConfigApplicationContext ioc = new AnnotationConfigApplicationContext(ImportConfig.class);
String[] beans = ioc.getBeanDefinitionNames();
for (String bean : beans) {
System.out.println(bean);
}
}
ImportSelector
- ImportSelector 导入选择器 配置
@Configuration
@Import(MyImportSelector.class)
public class ImportSelectorConfig {
}
- 配置MyImportSelector
public class MyImportSelector implements ImportSelector {
/**
*
* @param importingClassMetadata 元注解
* @return
*/
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
String[] arr = new String[8];
arr[0] = "com.alex.person.Color"; //这里写要注入的类的全类名,
return arr;
}
}
- 测试
@Test
void testImportSelector() {
AnnotationConfigApplicationContext ioc = new AnnotationConfigApplicationContext(ImportSelectorConfig.class);
String[] beans = ioc.getBeanDefinitionNames();
for (String bean : beans) {
System.out.println(bean);
}
}
小结: 重写selectImports是自动配置类的核心原理了, 自动配置就是通过重写这个方法, 把所有全类名注入的.
实现ImportBeanDefinitionRegistrar接口
- 手工注册 测试代码
- 实现ImportBeanDefinitionRegistrar接口
- 逻辑是如果存在"red"或者"com.alex.person.Color"这两个bean就将名为"rainbow"的bean注册到容器中
public class MyImportBeanRegisterar implements ImportBeanDefinitionRegistrar {
/**
*
* @param importingClassMetadata 当前类的注解信息
* @param registry 所以bean的定义都在这注册
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean definition = registry.containsBeanDefinition("red");
boolean definition2 = registry.containsBeanDefinition("com.alex.person.Color");
if (definition || definition2) {
RootBeanDefinition beanDefinition = new RootBeanDefinition(Rainbow.class);
registry.registerBeanDefinition("rainbow", beanDefinition);
}
}
}
@Configuration
@Import({MyImportBeanRegisterar.class})
public class ImportSelectorConfig {
}
使用FactoryBean
特点
- 是个接口
- 会调用这个接口的getObject方法创建对象加入容器.
使用方法
- 实现接口FactoryBean
- 注入容器
public class ColorFactory implements FactoryBean<Color> {
@Override
public Color getObject() throws Exception {
return new Color(); // 注入的对象
}
@Override
public Class<?> getObjectType() {
return Color.class; // 注入的类型
}
@Override
public boolean isSingleton() {
return false; // 是否单例
}
}
- 编写注入ColorFactory的方法
@Configuration
public class ColorFactoryConfig {
@Bean
public ColorFactory colorFactory() {
return new ColorFactory();
}
}
- 测试
@Test
void testFactoryBean() {
AnnotationConfigApplicationContext ioc = new AnnotationConfigApplicationContext(ColorFactoryConfig.class);
String[] beans = ioc.getBeanDefinitionNames();
for (String bean : beans) {
System.out.println(bean);
}
Object colorFactory = ioc.getBean("colorFactory");//获取
System.out.println(colorFactory.getClass());
}
- 结果 看着是向容器中导入了工厂bean, 实际调用工厂创建了对象加入了ioc容器
colorFactoryConfig
colorFactory
class com.alex.person.Color //居然注入了Color
- 获取工厂本身 给beanid 前面加 '&' "&colorFactory"
@Test
void testFactoryBean() {
AnnotationConfigApplicationContext ioc = new AnnotationConfigApplicationContext(ColorFactoryConfig.class);
String[] beans = ioc.getBeanDefinitionNames();
for (String bean : beans) {
System.out.println(bean);
}
Object colorFactory = ioc.getBean("&colorFactory");//获取工厂本身
System.out.println(colorFactory.getClass());
}
- 结果
colorFactoryConfig
colorFactory
class com.alex.import2.ColorFactory