@Import注解,顾名思义,导入,即把类加入Spring IOC容器。
有多种方式能让类加IOC容器管理,如@Bean、@Component等,@Import是另外一种方式,更加快捷。
1、三种用法
@Import有三种用法:
- .class数组方式;
- ImportSelector方式(Spring Boot底层采用比较得多的方式);
- ImportBeanDefinitionRegistrar方式
1.1、.class数组方式
假设有两个要加入IOC容器的类TestA、TestB……
@Data
public class TestA {
private Integer id = 1;
private String name = "TestA";
public void print(){
System.out.println(this.toString());
}
}
@Data
public class TestB {
private Integer id = 2;
private String name = "TestB";
public void print(){
System.out.println(this.toString());
}
}
在任何一个配置类上加@Import({TestA.class, TestB.class})……
@Import({TestA.class, TestB.class})
@Configuration
public class ImportConfig {}
然后就行了……
随便写点代码测试一下:
@RestController
@RequestMapping("/import")
public class TestImportController {
@Autowired
private TestA testA;
@Autowired
private TestB testB;
@RequestMapping("/test1")
public void test1(){
testA.print();
testB.print();
}
}
print:
TestA(id=1, name=TestA)
TestB(id=2, name=TestB)
1.2、ImportSelector方式
这种方式要写个类实现ImportSelector接口,重写selectImports()方法,返回的是要导入到容器中的类的全类名数组。
假设有个要加入IOC容器的类TestC……
@Data
public class TestC {
private Integer id = 3;
private String name = "TestC";
public void print(){
System.out.println(this.toString());
}
}
然后随便写个类实现ImportSelector接口……
public class TestImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{"com.xmotor.test_import_annotation.model.TestC"};
}
}
然后用@Import注解导入这个类就行了……
@Import({TestImportSelector.class})
@Configuration
public class ImportConfig {}
再随便写点代码测试一下:
@RestController
@RequestMapping("/import")
public class TestImportController {
@Autowired
private TestC testC;
@RequestMapping("/test2")
public void test2(){
testC.print();
}
}
print:
TestC(id=3, name=TestC)
1.3、ImportBeanDefinitionRegistrar方式
这种方式和前一种方式类似,也是写个类实现ImportBeanDefinitionRegistrar接口,重写registerBeanDefinitions()方法,不过这种方式可以自定义Bean在容器中的名称。
也是假设有个要加入IOC容器的类TestD……
@Data
public class TestD {
private Integer id = 4;
private String name = "TestD";
public void print(){
System.out.println(this.toString());
}
}
然后随便写个什么类实现ImportBeanDefinitionRegistrar接口……
public class TestImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) {
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(TestD.class);
registry.registerBeanDefinition("testD1111",rootBeanDefinition);//自定义注册bean
}
}
再然后就像上面一样用@Import注解导入这个类就行了……
@Import({TestImportBeanDefinitionRegistrar.class})
@Configuration
public class ImportConfig {}
再像上面一样随便搞点代码测试一下:
@RestController
@RequestMapping("/import")
public class TestImportController {
@Autowired
private TestD testD;
@RequestMapping("/test3")
public void test3(){
testD.print();
}
}
print:
TestD(id=4, name=TestD)
1.4、注意点
三种用法方式都可在一个@Import中使用,需要注意的是第一种、第二种方式在IOC容器中bean名称是类的全类名,而第三种方式是自定义的名称。
三种方式一起导入……
@Import({TestA.class,
TestB.class,
TestImportSelector.class,
TestImportBeanDefinitionRegistrar.class})
@Configuration
public class ImportConfig {}
搞点代码打印Bean注册名称看一下……
@RestController
@RequestMapping("/import")
public class TestImportController {
@RequestMapping("/getBeanDefinitionNames")
public void test() throws Exception{
AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(ImportConfig.class); //这里的参数代表要做操作的类
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String name : beanDefinitionNames){
System.out.println(name);
}
}
}
打印结果一看就懂就不浪费口水多做解释了……