Spring Boot基础(二)自动配置:Import注解
Enbale的基本:Import注解
@Enbale底层依赖于@Import注解导入一些类,使用Import导入的类会被Spring加载到IoC容器中,而@Import提供了4中用法:
- 导入Bean:直接导入实体类
- 导入配置类:导入配置类中定义的所有Bean
- 导入ImportSelect实现类,用于加载配置文件中的类
- 导入ImportBeanDefinitionRegistrar实现类
直接导入Bean
@SpringBootApplication @Import(User.class) //导入实体类 public class SprintbootMyUnApplication { public static void main(String[] args) { //启动SpringBoot,获取Ioc ConfigurableApplicationContext context = SpringApplication.run(SprintbootMyUnApplication.class, args); //直接根据实体类的class获取bean User bean = context.getBean(User.class);
//获得的是一个map,从map中可以查看Bean的名称,一般是类的全限定名 Map<String, User> beans = context.getBeansOfType(User.class);
System.out.println(bean); System.out.println(beans); }
导入配置类
@SpringBootApplication //UserConfig中定义的所有类,都会被创建 @Import(UserConfig.class) //@EnableUser //@Import(User.class) public class SprintbootMyUnApplication { public static void main(String[] args) { //启动SpringBoot,获取Ioc ConfigurableApplicationContext context = SpringApplication.run(SprintbootMyUnApplication.class, args);
Object user = context.getBean("user153"); Object role = context.getBean("role"); System.out.println(user); System.out.println(role); }
配置类(注意包名要对上):
@Configuration //当使用Import注解导入这个配置类时,这个注解可加可不加 public class UserConfig { @Bean public User user153(){ return new User(); } @Bean public Role role(){ return new Role(); } }
导入ImportSelect实现类
Spring Boot官方就是用的这种方式,路径:@SpringBootApplication——>@EnableAutoConfiguration——>@Import(AutoConfigurationImportSelector.class)——>AutoConfigurationImportSelector。
AutoConfigurationImportSelector实现了DeferredImportSelector接口,而DeferredImportSelector实现了ImportSelector接口。后面会详细介绍这个实现类
@SpringBootApplication //imports实现了ImportSelect接口的实现类,也可以导入Bean @Import(MyImportSelector.class) public class SprintbootMyUnApplication { public static void main(String[] args) { //启动SpringBoot,获取Ioc ConfigurableApplicationContext context = SpringApplication.run(SprintbootMyUnApplication.class, args); Object user = context.getBean(User.class); Object role = context.getBean(Role.class); System.out.println(user); System.out.println(role); }
实现类:
public class MyImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) {
//这里的字符串可以动态替换 return new String[]{"com.yz.domin.Role","com.yz.domin.User"}; } }
导入ImportBeanDefinitionRegistrar实现类
@SpringBootApplication //@ComponentScan("com.yz.config") //@Import(UserConfig.class) //@EnableUser //@Import(User.class) //@Import(MyImportSelector.class) @Import(MyImportBeanDefinitionRegistrar.class) public class SprintbootMyUnApplication { public static void main(String[] args) { //启动SpringBoot,获取Ioc ConfigurableApplicationContext context = SpringApplication.run(SprintbootMyUnApplication.class, args); //导入User,因为Role没有被创建 Object user = context.getBean("user88"); //Object role = context.getBean(Role.class); System.out.println(user); //System.out.println(role); }
实现类:
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { //手动向Ioc容器里注入Bean //定义bean的类型 AbstractBeanDefinition definition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition(); //定义bean的名字 registry.registerBeanDefinition("user88", definition); } }
EnableAutoConfiguration注解
@EnableAutoConfiguration注解内部使用@Import(AutoConfigurationImportSelector.class) 来加载配置类,这个AutoConfigurationImportSelector就是基于ImportSelector实现的
在源码中对应路径:
@SpringBootApplication——>@EnableAutoConfiguration——>@Import(AutoConfigurationImportSelector.class)——>AutoConfigurationImportSelector类——>getCandidateConfigurations()。
在这个方法中,使用SpringFactoriesLoader.loadFactoryNames()方法获取到一个字符串集合,这些就是被加载出来的bean,来源就是META-INF/spring.factories配置文件,该文件中定义了大量配置类当SpringBoot应用启动时,会自动加载这些配置类,并初始化bean。如果configurations 集合为空,在META-INF/spring.factories文件里找不到自动配置类,就会报出异常
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader()); Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you " + "are using a custom packaging, make sure that file is correct."); return configurations; }
这个META-INF/spring.factories的文件就在springboot自动配置的包里:org.sprintbootframework.boot:spring-boot-autoconfigure:version
spring.factories文件
这里所有的Configraution都是会被加载的(多数都会有ConditionalOnXXX条件注解来按条件创建)
# Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\ org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\ org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\ org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\ org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
………………
本文来自博客园,作者:我永远喜欢石原里美,转载请注明原文链接:https://www.cnblogs.com/yuan-zhou/p/15795352.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理