白话@Import注解
白话@Import注解
-
- @Import三种使用方式:
-
- 1.直接使用:
- 2.ImportSelector:
- 3.ImportBeanDefintionRegister:
- 什么时候会用到@Import:
🍅你的点赞是我分享的动力🍅
面试的时候,面试官经常会问这样一个问题: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
。