🍅你的点赞是我分享的动力🍅
面试的时候,面试官经常会问这样一个问题:SpringBoot中,向IOC容器添加对象有哪几种方式?
大多数人能回答以下几种:
- @Configuration+@Bean
- @Controller @Service @Repository @Component等注解,通过扫描纳入Spring管理。
- 手动注册(DefaultListableBeanFactory)
- @Import
今天讲一下容易被忽略的一个方式:@Import
首先要明确一点,@Import
注解通常和@Configuration
注解配合使用。
@Import三种使用方式:
第一种用法:@Import({ 要导入的容器中的组件 } ):容器会自动注册这个组件,id默认是全类名
1.直接使用:
目标User类:
public class User {
...
}
配置类:
@Configuration
@Import(User.class)
public class ConfigBean {
...
}
这种方式是在@Import
注解中声明目标对象的Class对象
如果我们要注入多个对象,可以用数组的形式,用逗号分隔:
@Import({User2.class,User.class})
2.ImportSelector:
第二种用法:ImportSelector:返回需要导入的组件的全类名数组,springboot底层用的特别多。
ImportSelector是什么呢?和@Import
有什么关系呢?
我们去看看源码:
public interface ImportSelector {
String[] selectImports(AnnotationMetadata var1);
@Nullable
default Predicate<String> getExclusionFilter() {
return null;
}
}
可以看到ImportSelector是Spring提供的一个接口,其中有一个selectImports方法需要我们去重写,方法返回的是一个String数组。
这个String数组是什么呢,我们先不管它。
现在编写一个自定义类实现ImportSelector接口:
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
//前面可以是和业务相关的逻辑
//返回需要导入的组件的全类名数组
return new String[]{"com.example.es.bean.User"};
}
}
配置类:
@Configuration
@Import(MyImportSelector.class)
public class ConfigBean {
...
}
现在我们了解了,ImportSelector接口时为了返回一个String数组,这个数组中包含了所有将要注册进Spring容器的对象的全类名。
看过SpringBoot源码的同学应该更容易理解这里,SpringBoot是如何进行自动化配置的,是如何加载默认jar包进IOC容器的。 和ImportSelector+@Import
不无关系。
3.ImportBeanDefintionRegister:
第三种用法:ImportBeanDefinitionRegistrar:手动注册bean到容器
ImportBeanDefintionRegister是什么?是一个接口,实现这个接口重写方法,手动注册Bean!
public class MyImportBeanDefintionRegister implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
BeanDefinition beanDefinition = new RootBeanDefinition(User.class);
registry.registerBeanDefinition("User", beanDefinition);
//registry.registerBeanDefinition("User2", beanDefinition2);
...
}
}
配置类:
@Configuration
@Import(MyImportBeanDefintionRegister.class)
public class ConfigBean {
...
}
什么时候会用到@Import:
你可以特别注意上面的方式二,方式二注入目标对象,不需要引入目标对象的类,只需要知道你的类路径。
这和什么很像? 没错,就是反射,通过全路径拿到类的全部信息。
那么什么时候用呢?一句话
项目启动的时候,需要加载注入第三方对象(jar包)或者编写一些业务逻辑的时候使用
@Import
。