专业定制网站制作公司,江苏水利建设网站,单页网站有哪些,微信开放平台是什么文章目录 前言一、了解相关注解1.Condition注解2.Enable注解 二、SpringBoot自动配置1.SpringBootApplication注解2.SpringBootConfiguration注解3.EnableAutoConfiguration注解4.Conditional注解 总结 前言
Spring Boot 自动配置是 Spring Boot 的核心特性之一#xff0c;它… 文章目录 前言一、了解相关注解1.Condition注解2.Enable注解 二、SpringBoot自动配置1.SpringBootApplication注解2.SpringBootConfiguration注解3.EnableAutoConfiguration注解4.Conditional注解 总结 前言
Spring Boot 自动配置是 Spring Boot 的核心特性之一它的目标是通过分析应用程序的类路径classpath和依赖关系来自动配置 Spring 应用程序所需的 Bean、设置和组件。这意味着开发人员不需要手动配置大部分常见的 Spring 组件Spring Boot 将根据环境和依赖来进行智能配置。这样开发人员可以专注于编写业务逻辑而不必过多关心底层配置细节。 一、了解相关注解
1.Condition注解
Condition 是在Spring 4.0 增加的条件判断功能通过这个可以功能可以实现选择性的创建 Bean 操作。 SpringBoot 提供的常用条件注解
ConditionalOnProperty判断配置文件中是否有对应属性和值才初始化BeanConditionalOnClass判断环境中是否有对应字节码文件才初始化BeanConditionalOnMissingBean判断环境中没有对应Bean才初始化BeanConditionalOnBean判断环境中有对应Bean才初始化Bean
2.Enable注解
SpringBoot中提供了很多Enable开头的注解这些注解都是用于动态启用某些功能的。而其底层原理是使用Import注 解导入一些配置类实现Bean的动态加载。 Enable底层依赖于Import注解导入一些类使用Import导入的类会被Spring加载到IOC容器中。而Import提供4中用法 ① 导入Bean Import(User.class) ② 导入配置类 Import(UserConfig.class) ③ 导入 ImportSelector 实现类。一般用于加载配置文件中的类 Import(MyImportSelector.class) ④ 导入 ImportBeanDefinitionRegistrar 实现类。 Import({MyImportBeanDefinitionRegistrar.class})
二、SpringBoot自动配置
1.SpringBootApplication注解
主启动类注解:
package org.springframework.boot.autoconfigure;
Targer(ElementType.TYPE)//作用于类
Retention(Retention.RUNTIME)//该注解在运行时可见可以通过反射读取
Documented//文档相关
Inherited//可以被子类继承
SpringBootConfiguration//标记该类为 Spring Boot 的配置类
EnableAutoConfiguration//实现自动配置功能
ComponentScan(excludeFilters {Filter(typeFilterType.CUSTOM,classes TypeExcludeFilter.class),Filter(typeFilterType.CUSTOM,classes AutoConfigurationExcludeFilter.class)
})//配置组件扫描以查找和注册 Spring Bean
public interface SpringBootApplication{……}总的来说大概可以把SpringBootApplication看作是Configuration、EnableAutoConfigeration、ComponentScan注解的集合。 EnableAutoConfigeration启用SpringBoot的自动配置机制 ComponentScan扫描被ComponentServiceController注解的bean注解默认会扫描该类所在包下的所有的类 Configuration允许在上下文中注册额外的bean或倒入其他配置类。
2.SpringBootConfiguration注解
SpringBoot的配置类 标注在某个类上 表示这是一个SpringBoot的配置类
//这里的Configuration说明这是一个配置类 配置类就是对应Spring的xml 配置文件
Configuration
public interface SpringBootConfiguration {}
//里面的 Component 这就说明启动类本身也是Spring中的一个组件而已负责启动应用
Component
public interface Configuration {....}3.EnableAutoConfiguration注解
EnableAutoConfiguration开启自动配置功能,它可以说是我们研究SpringBoot 自动配置的重中之重了
Target({ElementType.TYPE})
Retention(RetentionPolicy.RUNTIME)
Documented
Inherited
AutoConfigurationPackage
Import({AutoConfigurationImportSelector.class})
public interface EnableAutoConfiguration {.....}3.1AutoConfigurationPackage注解
//AutoConfigurationPackage的子注解
//Registrar.class 作用将主启动类的所在包及包下面所有子包里面的所有组件扫描到Spring容器
Import({Registrar.class})
public interface AutoConfigurationPackage {
}在默认的情况下就是将主配置类(SpringBootApplication)的所在包及其子包里边的组件扫描到Spring容器中。
3.2Import({AutoConfigurationImportSelector.class})注解给容器导入组件 AutoConfigurationImportSelector 自动配置导入选择器给容器中导入一些组件 通过了import注解导入了AutoConfigurationImportSelector这个配置类根据类名可以发现这个实现类是Import提供4中用法中的ImportSelector的实现类那么它就一定实现了selectImports这个个方法
String[] selectImports(AnnotationMetadata importingClassMetadata);该方法的主要目的是根据运行时的条件或配置动态地确定要导入哪些配置类以扩展或自定义 Spring 应用程序的配置。 返回值是一个字符串数组其中包含需要导入到当前配置类中的其他配置类的全限定类名。 那我们就来看看他是怎么来重写这个方法的 public String[] selectImports(AnnotationMetadata annotationMetadata) {if (!this.isEnabled(annotationMetadata)) {return NO_IMPORTS;} else {AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry this.getAutoConfigurationEntry(annotationMetadata);return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());}}this.isEnabled(annotationMetadata) 方法检查是否启用了自动配置。如果没有启用就返回一个空数组 NO_IMPORTS表示不导入任何配置类。 getAutoConfigurationEntry(annotationMetadata) 方法来获取自动配置入口,那么他是如何去获取的呢继续进方法看看
ListString configurations this.getCandidateConfigurations(annotationMetadata, attributes);用于根据给定的注解元数据 (annotationMetadata) 和属性 (attributes) 获取潜在的自动配置类的列表它的作用就是找到所有可能与应用程序上下文相关的自动配置类。 ↓ ↓ ↓
protected ListString getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {ListString configurations new ArrayList(SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader()));ImportCandidates.load(AutoConfiguration.class, this.getBeanClassLoader()).forEach(configurations::add);Assert.notEmpty(configurations, No auto configuration classes found in META-INF/spring.factories nor in META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. If you are using a custom packaging, make sure that file is correct.);return configurations;}这个方法想告诉我们什么呢其实看到这里官方给出的提示就已经很明显了 在META-INF/spring中找不到自动配置类。在META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports中。如果您正在使用自定义打包请确保该文件是正确的。 简但来说就是在所有包名叫做autoConfiguration的包下面都有META-INF/spring.factories文件Spring启动的时候会扫描这个文件将其文件包装成Properties对象从Properties对象获取到key值为EnableAutoConfiguration的数据然后添加到容器里边。 4.Conditional注解
现在SpringBoot自动配置信息有了自动配置还差什么呢 到这一步为止SpringBoot已经为我们的项目中导入了大量的自动配置类且项目中的自动配置类全部执行但是这133个自动配置类我们都会用到吗 以RedisAutoConfiguration为例: 看到这里就不难发现虽然SpringBoot帮我们加载了Redis的自动配置类但并没有把redisTemplate模板类帮我们注入容器真正想要注入模板类到容器里供我们使用之前还要经过一些选择注解的判断且全部成功才可以成功注入。 以redisTemplate模板类为例它想要成功注入就得经过三个选择注解的全部成功才可以注入
//项目中必须要有RedisProperties这个类才可以生效坐标中倒入
EnableConfigurationProperties({RedisProperties.class})
//容器中必须没有一个Bean为redisTemplate这也就允许我们自己向容器中注入一个redisTemplate
ConditionalOnMissingBean(name {redisTemplate})//指定必须是单例工厂才能生效
ConditionalOnSingleCandidate(RedisConnectionFactory.class)只有在经过这三个选择注解后自动装配才算真正完成redisTemplate类才能供我们在项目中使用。 总结
EnableAutoConfiguration 注解内部使用Import(AutoConfigurationImportSelector.class)来加载配置类配置文件位置META-INF/spring.factories该配置文件中定义了大量的配置类当 SpringBoot应用启动时会自动加载这些配置类初始化Bean并不是所有的Bean都会被初始化在配置类中使用Condition来加载满足条件的Bean。