文章目录
@Import的四种用法
@Import的四种用法为:
- 导入Bean对象
- 导入配置类
- 导入的是ImportSelector实现类
- 导入的是ImportDefinitionRegistrar的实现类
对应的测试代码如下所示:
@SpringBootApplication
@Import(User.class) //导入的Bean对象
public class SpringbootEnableApplication {
public static void main(String[] args) {
//获取Spring中的IOC容器
ConfigurableApplicationContext application = SpringApplication.run(SpringbootEnableApplication.class, args);
//获取容器中的user这个bean对象
Object user = application.getBean(User.class);
System.out.println(user); //输出com.example.springboot_enable.domain.User@130e116b
}
}
如果我们要导入的是配置类中时,那么上面的代码中@Import改为@Import(配置类的字节码对象)
即可,则对应的配置类代码为:
/*
@Configuration 如果有在这个配置类的上方使用了注解@Configuration,那么
说明这个类是一个配置类,此时就已经将这个对象添加到了IOC容器中了。那么这时候
即使没有在测试类上方使用@Import注解来导入这个配置类的bean对象,那么也能够正常运行。
*/
public class UserConfig {
@Bean("user_config") //如果注解Bean没有设置属性值的话,那么bean的id默认为返回值的类名的小写形式,如果有设置的话,那么id就是我们设置的值
public User user(){
return new User();
}
}
对应的测试类的代码为:
@SpringBootApplication
@Import(UserConfig.class) //导入的是配置类
public class SpringbootEnableApplication {
public static void main(String[] args) {
//获取Spring中的IOC容器
ConfigurableApplicationContext application = SpringApplication.run(SpringbootEnableApplication.class, args);
//获取jar包中的User类型的Bean对象
//Object user = application.getBean(User.class);
Object user = application.getBean("user_config");
System.out.println(user); //输出com.example.springboot_enable.domain.User@66c92293
}
}
如果我们导入的是ImportSelector的实现类,那么这时候在调用getBean方法来获取Bean对象的时候,只能传递对应的字节码对象,对应的代码为:
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{"com.example.springboot_enable.domain.User"};
}
}
测试类代码:
@SpringBootApplication
@Import(MyImportDefinitionRegistrar.class)
public class SpringbootEnableApplication {
public static void main(String[] args) {
//获取Spring中的IOC容器
ConfigurableApplicationContext application = SpringApplication.run(SpringbootEnableApplication.class, args);
//获取jar包中的User类型的Bean对象
Object user = application.getBean(User.class);
System.out.println(user);
}
}
但是如果发生这样的错误,如下所示:
表示得知User这个bean对象并不是唯一的,原来是因为我们上面的配置类UserConfig中使用了注解@Configuration
,从而已经注入了一个User类型的Bean对象了,这时候再通过实现类到注入一个User类型的Bean对象,这时候因为是通过getBean(User.class)来获取对应的Bean对象,所以就会因为存在多个User类型的Bean对象,从而不知道要取得是哪一个User类型的Bean对象而发生报错。所以如果需要测试导入ImportSelector的时候,那么就需要将配置类中的@Configuration注解掉即可,然后就可以正常运行,输出com.example.springboot_enable.domain.User@141e5bef
如果需要导入的是ImportDefinitonRegistrar的实现类,那么这时候我们需要在这个实现类中将对应的Bean对象注册到IOC容器中,然后在测试类中,通过@Import来注入这个实现类,最后调用getBean方法,就可以获取到对应的id的Bean对象了,对应的代码为:
public class MyImportDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
registry.registerBeanDefinition("user",new RootBeanDefinition(User.class));
}
}
测试类:
@SpringBootApplication
@Import(MyImportDefinitionRegistrar.class)
public class SpringbootEnableApplication {
public static void main(String[] args) {
//获取Spring中的IOC容器
ConfigurableApplicationContext application = SpringApplication.run(SpringbootEnableApplication.class, args);
//获取IOC容器中User类型的Bean对象
Object user = application.getBean(User.class);
System.out.println(user);//输出com.example.springboot_enable.domain.User@141e5bef
//获取IOC容器中id为user_registrar的User类型的Bean对象
User user2 = application.getBean("user_registrar", User.class);
System.out.println(user2);//输出com.example.springboot_enable.domain.User@141e5bef
System.out.println(user == user2); //输出true(容器中只有一个User类型的Bean对象)
}
}
⭐⭐⭐在导入Bean对象以及导入的是ImportSelector的实现类的时候,如果需要获取IOC容器中的bean对象的时候,通过application调用getBean方法来获取的时候,需要传递的参数只能是对应的字节码对象,而不可以是这个bean对象的id,因为没有设置这个id,所以这时候如果我们通过id来获取bean对象的时候,就会提示这个bean是不存在的。但是通过导入配置类以及ImportDefinitionRegistrar的实现类的时候,则可以通过bean的id来获取对应的bean对象,只是导入配置类的时候,bean的id默认是这个类名的小写形式,当然也可以自定义的,例如@Bean("xxx")
即可自定义bean的id为xxx,而导入ImportDefinitionRegistrar则必须要设置bean的id。