@EnableXXX 注解的底层其实就是使用了 @Import 注解的功能
# @Import 注解
@Enable * 底层依赖于 @Import 注解导入一些类,使用 @Import 导入的类会被 Spring 加载到 IOC 容器中。而 @Import 提供 4 种用法:
- 导入 Bean
- 导入配置类
- 导入 ImportSelector 实现类。一般用于加载配置文件中的类
- 导入 ImportBeanDefinitionRegistrar 实现类。
# 导入 Bean
项目结构:
User 类与 Role 类
public class User { } | |
public class Role { } |
启动类
// @ComponentScan 扫描范围:当前引导类所在包及其子包 | |
// com/dkx1 | |
// com/dkx | |
// 两个路径同级路径项目可以被扫描到 | |
@Import({User.class, Role.class}) | |
@SpringBootApplication | |
public class SpringBootEnableApplication { | |
public static void main(String[] args) { | |
ConfigurableApplicationContext run = SpringApplication.run(SpringBootEnableApplication.class, args); | |
// Import 导入了 User 但是名称不确定所以使用类的类型来获取 Bean | |
User user = run.getBean(User.class); | |
System.out.println(user); | |
System.out.println("-------------------------"); | |
Role role = run.getBean(Role.class); | |
System.out.println(role); | |
System.out.println("-----------获取Bean的名字-----------"); | |
Map<String, User> users = run.getBeansOfType(User.class); | |
System.out.println(users); // {com.dkx.domain.User=com.dkx.domain.User@3241713e} | |
System.out.println("-------------------------"); | |
System.out.println("-----------通过获取到Bean的名称来获取Bean-----------"); | |
Object bean = run.getBean("com.dkx.domain.User"); | |
System.out.println(bean); | |
} | |
} |
运行结果:
# 导入配置类
User 类和 Role 类
public class Role { } | |
public class User { } |
UserConfig 类
public class UserConfig { | |
@Bean | |
public User user() { | |
return new User(); | |
} | |
@Bean | |
public Role role() { | |
return new Role(); | |
} | |
} |
启动类
// @ComponentScan 扫描范围:当前引导类所在包及其子包 | |
// com/dkx1 | |
// com/dkx | |
// 两个路径同级路径项目可以被扫描到 | |
@Import(UserConfig.class) | |
@SpringBootApplication | |
public class SpringBootEnableApplication { | |
public static void main(String[] args) { | |
ConfigurableApplicationContext run = SpringApplication.run(SpringBootEnableApplication.class, args); | |
System.out.println("==========UserBean=========="); | |
Object user = run.getBean("user"); | |
System.out.println(user); | |
System.out.println("==========RoleBean=========="); | |
Object role = run.getBean("role"); | |
System.out.println(role); | |
} | |
} |
运行结果:
# 导入 ImportSelector 实现类
创建一个 MyImportSelector 类
编写 MyImportSelector 类
public class MyImportSelector implements ImportSelector { | |
@Override | |
public String[] selectImports(AnnotationMetadata importingClassMetadata) { | |
// 配置的 Bean 的路径是一个字符串意味着可以不用写死了,可以动态的加载类 | |
return new String[]{"com.dkx.domain.Role", "com.dkx.domain.User"}; | |
} | |
} |
启动类
// @ComponentScan 扫描范围:当前引导类所在包及其子包 | |
// com/dkx1 | |
// com/dkx | |
// 两个路径同级路径项目可以被扫描到 | |
@Import(MyImportSelector.class) | |
@SpringBootApplication | |
public class SpringBootEnableApplication { | |
public static void main(String[] args) { | |
ConfigurableApplicationContext run = SpringApplication.run(SpringBootEnableApplication.class, args); | |
System.out.println("==========UserBean=========="); | |
User user = run.getBean(User.class); | |
System.out.println(user); | |
System.out.println("==========RoleBean=========="); | |
Role role = run.getBean(Role.class); | |
System.out.println(role); | |
} | |
} |
运行结果:
# 导入 ImportBeanDefinitionRegistrar 实现类
创建一个 ImportBeanDefinitionRegistrar 实现类
编写 ImportBeanDefinitionRegistrar 实现类代码注册 Bean
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { | |
/** | |
* @param importingClassMetadata annotation metadata of the importing class | |
* @param registry current bean definition registry 向 IOC 中注入某一些对象 | |
*/ | |
@Override | |
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { | |
// 构建 Bean | |
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition(); | |
// 注册 Bean | |
// 参数 1:Bean 的名称,参数 2:Bean 类型 | |
registry.registerBeanDefinition("user", beanDefinition); | |
} | |
} |
启动类
// @ComponentScan 扫描范围:当前引导类所在包及其子包 | |
// com/dkx1 | |
// com/dkx | |
// 两个路径同级路径项目可以被扫描到 | |
@Import(MyImportBeanDefinitionRegistrar.class) | |
@SpringBootApplication | |
public class SpringBootEnableApplication { | |
public static void main(String[] args) { | |
ConfigurableApplicationContext run = SpringApplication.run(SpringBootEnableApplication.class, args); | |
System.out.println("==========UserBean=========="); | |
User user = run.getBean(User.class); | |
System.out.println(user); | |
System.out.println("==========使用注册时的名称来获取Bean=========="); | |
// 在 MyImportBeanDefinitionRegistrar 中注册 Bean 的时候定义了 Bean 的名称为 user | |
Object user1 = run.getBean("user"); | |
System.out.println(user1); | |
} | |
} |
运行结果: