标题:Spring Boot中的@Import
在Spring Boot中的@Enable*底层依赖于@Import注解导入一些类,使用@Import导入的类会被Spring加载到IoC容器当中去。而@Import提供了四种用法:
1. 导入Bean
//User类
public class User {
}
//配置类
@Configuration
public class UserConfig {
@Bean
public User user() {
return new User();
}
}
//引导类
@Import(User.class)
public class SpringbootEnableApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);
//获取Bean
/*Object user = context.getBean("user");
System.out.println(user);*/
//通过类型获取
User user = context.getBean(User.class);
System.out.println(user);
//getBeansOfType()可以获取到Bean的名称,返回一个Map集合
Map<String, User> beansOfType = context.getBeansOfType(User.class);
//{com.itheima.domain.User(Key)=com.itheima.domain.User@c68a5f8(Value)}
System.out.println(beansOfType);
}
}
2. 导入配置类,如果使用的是@Import导入配置类,配置类上的@Configuration可以省略不写
public class Role {
}
public class User {
}
@Configuration //可以省略
public class UserConfig {
@Bean
public User user() {
return new User();
}
@Bean
public Role role() {
return new Role();
}
}
@Import(UserConfig.class)
public class SpringbootEnableApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);
//通过类型获取
User user = context.getBean(User.class);
System.out.println(user); //com.itheima.domain.User@5173200b
Role role = context.getBean(Role.class);
System.out.println(role); //com.itheima.domain.Role@25c5e994
}
}
3. 导入ImportSelector实现类。一般用于加载配置文件当中的类
public class User {
}
public class Role {
}
public class MyImportSelector implements ImportSelector {
/**
* Select and return the names of which class(es) should be imported based on
* the {@link AnnotationMetadata} of the importing @{@link Configuration} class.
*
* @param importingClassMetadata
* @return the class names, or an empty array if none
*/
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.itheima.domain.User","com.itheima.domain.Role"};
}
}
@Import(MyImportSelector.class)
public class SpringbootEnableApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);
//获取Bean
/*Object user = context.getBean("user");
System.out.println(user);*/
//通过类型获取
User user = context.getBean(User.class);
System.out.println(user); //com.itheima.domain.User@3bc735b3
Role role = context.getBean(Role.class);
System.out.println(role); //com.itheima.domain.Role@577f9109
//getBeansOfType()可以获取到Bean的名称
/*Map<String, User> beansOfType = context.getBeansOfType(User.class);
System.out.println(beansOfType);*/
}
}
4. 导入ImportBeanDefinitionRegistrar实现类
public class User {
}
@Import(MyImportBeanDefinitionRegistrar.class)
public class SpringbootEnableApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);
//获取Bean
/*Object user = context.getBean("user");
System.out.println(user);*/
/**
* user:就是在MyImportBeanDefinitionRegisttrar中的名称
* registry.registerBeanDefinition("user",beanDefinitionBuilder.getBeanDefinition());
*/
Object user1 = context.getBean("user");
System.out.println(user1); //com.itheima.domain.User@577f9109
//通过类型获取
User user = context.getBean(User.class);
System.out.println(user); //com.itheima.domain.User@577f9109
Role role = context.getBean(Role.class);
System.out.println(role); //No qualifying bean of type 'com.itheima.domain.Role' available:因为没有导入,所以会失败
//getBeansOfType()可以获取到Bean的名称
/*Map<String, User> beansOfType = context.getBeansOfType(User.class);
System.out.println(beansOfType);*/
}
}
package com.itheima.config;
import com.itheima.domain.User;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/**
* Register bean definitions as necessary based on the given annotation metadata of
* the importing {@code @Configuration} class.
* <p>Note that {@link BeanDefinitionRegistryPostProcessor} types may <em>not</em> be
* registered here, due to lifecycle constraints related to {@code @Configuration}
* class processing.
* <p>The default implementation is empty.
*
* @param importingClassMetadata annotation metadata of the importing class
* @param registry current bean definition registry 可以向IoC容器注入某个对象
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(User.class);
/**
* IoC工厂中去注册Bean
* registerBeanDefinition:
* String beanName:给Bean取一个名称(user)
* BeanDefinition beanDefinition : bean的类型就是User.class
*/
registry.registerBeanDefinition("user",beanDefinitionBuilder.getBeanDefinition());
}
}
常用的是第三种方式:在@SpringBootApplication(Spring Boot最核心的注解)中
进入到@SpringBootApplication中,可以看到@EnableAutoConfiguration
进入到@EnableAutoConfiguration中可以看到@Import(AutoConfigurationImportSelector.class)
点进这个类当中可以看到AutoConfigurationImportSelector.class继承自DeferredImportSelector
进入到DeferredImportSelector中可以看到他实现了ImportSelector这个接口
这个接口便是第三种@Import常用的方式