-
SpringBoot的自动配置原理
2020-02-25 13:47:31一、SpringBoot的自动配置原理 SpringBoot 的自动化配置让我们的开发彻底远离了 Spring 繁琐的各种配置,让我们专注于开发,但是SpringBoot 的自动化配置是怎么实现的呢?下面为你揭开 SpringBoot 自动化配置的神秘...一、SpringBoot的自动配置原理
SpringBoot 的自动化配置让我们的开发彻底远离了 Spring 繁琐的各种配置,让我们专注于开发,但是SpringBoot 的自动化配置是怎么实现的呢?下面为你揭开 SpringBoot 自动化配置的神秘面纱。
所以今天来讲讲SpringBoot是如何实现自动配置的~
1.1三个重要的注解
我们可以发现,在使用
main()
启动SpringBoot的时候,必不可少的注解@SpringBootApplication
我们可以点击进去
@SpringBootApplication
注解中看看,它其实是由三个注解组成的组合注解:@SpringBootConfiguration
:底层是Configuration注解,说白了就是支持JavaConfig的方式来进行配置(使用Configuration配置类等同于XML文件)。@EnableAutoConfiguration
:开启自动配置功能@ComponentScan
:扫描注解,默认是扫描当前类下的package。将@Controller/@Service/@Component/@Repository等注解加载到IOC容器中。
1.2重点@EnableAutoConfiguration
我们知道SpringBoot可以帮我们减少很多的配置,也肯定听过“约定大于配置”这么一句话,那SpringBoot是怎么做的呢?其实靠的就是**@EnableAutoConfiguration**注解。
简单来说,这个注解可以帮助我们自动载入应用程序所需要的所有默认配置。
如果你的类路径下有
tomcat-embedded.jar
包,那么你很可能就需要TomcatServletWebServerFactory我们点进去看一下,发现有两个比较重要的注解:
@AutoConfigurationPackage
:自动配置包@Import
:给IOC容器导入组件
1.2.1 @AutoConfigurationPackage
网上将这个**@AutoConfigurationPackage注解解释成自动配置包**,我们也看看
@AutoConfigurationPackage
里边有什么:
我们可以发现,依靠的还是
@Import
注解,再点进去查看,我们发现重要的就是以下的代码:在默认的情况下就是将:主配置类(
@SpringBootApplication
)的所在包及其子包里边的组件扫描到Spring容器中。- 看完这句话,会不会觉得,这不就是ComponentScan的功能吗?这俩不就重复了吗?
我开始也有这个疑问,直到我看到文档的这句话:
it will be used when scanning for code @Entity classes. It is generally recommended that you place EnableAutoConfiguration (if you’re not using @SpringBootApplication) in a root package so that all sub-packages and classes can be searched.
比如说,你用了Spring Data JPA,可能会在实体类上写
@Entity
注解。这个@Entity
注解由@AutoConfigurationPackage
扫描并加载,而我们平时开发用的@Controller/@Service/@Component/@Repository
这些注解是由ComponentScan
来扫描并加载的。- 简单理解:这二者扫描的对象是不一样的。
1.2.2回到Import
我们发现它使用了 Spring 框架提供的 @Import 注解注入了注册 Bean 的配置类,在往下分析前,不妨先了解一下这个 @Import 注解,在我们平时使用 Spring 框架的 Enable* 类注解时,发现它们都有一个共同的特点,就是都有一个 @Import 注解,用来导入配置类,这些配置方式又分为三种类型:
- 直接导入配置类:@Import({xxxConfiguration.class})
- 依据条件选择配置类:@Import({xxxSelector.class})
- 动态注册 Bean:@Import({xxxRegistrar.class})
我们回到
@Import(AutoConfigurationPackages.Registrar.class)
这句代码上,再点进去AutoConfigurationPackages.Registrar.class
看看具体的实现是什么:/** * {@link ImportBeanDefinitionRegistrar} to store the base package from the importing * configuration. */ static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports { @Override public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) { register(registry, new PackageImport(metadata).getPackageName()); } @Override public Set<Object> determineImports(AnnotationMetadata metadata) { return Collections.singleton(new PackageImport(metadata)); } }
1.3总结
@SpringBootApplication等同于下面三个注解:
- @SpringBootConfiguration
- @EnableAutoConfiguration
- @ComponentScan
其中@EnableAutoConfiguration是关键(启用自动配置),内部实际上就去加载
META-INF/spring.factories
文件的信息,然后筛选出以EnableAutoConfiguration为key的数据,加载到IOC容器中,实现自动配置功能!参考: https://blog.csdn.net/zchdjb/article/details/90795633
-
SpringBoot 的自动配置原理
2020-09-06 08:36:40SpringBoot 的自动配置原理 1、Springboot启动之后会扫描这几个位置去加载配置文件 file:./config/ //当前项目的更目录下的config文件夹下 file:./ //当前项目的更目录下 classpath:/config/ //当前类路径...SpringBoot 的自动配置原理
1、Springboot启动之后会扫描这几个位置去加载配置文件
- file:./config/ //当前项目的更目录下的config文件夹下
- file:./ //当前项目的更目录下
- classpath:/config/ //当前类路径下(resources)的config文件夹下
- classpath:/ //当前类路径下的
以上按照优先级从高到低的顺序,所有位置的文件都会被加载,高优先级的覆盖低优先级的,这四个配置文件,会互补配置
2、外部配置的加载顺序
- 由Jar包外向内寻找配置文件:
- 优先加载带profile的
- 在加载不带profile
3、自动配置原理
配置文件里面应该写什么?怎么写?
原理:
-
SpringBoot启动时加载主配置类,开启自动改配置功能@EnableAutoConfiguration
-
@EnableAutoConfiguration的作用
-
利用AutoConfigurationImportSelector给容器导入组件
@Import(AutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration {
@Override public String[] selectImports(AnnotationMetadata annotationMetadata) { if (!isEnabled(annotationMetadata)) { return NO_IMPORTS; } AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata); return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations()); }
2.扫描所以Jar包路径下的 META-INF/Spring.factories,把扫描到的文件包装成properties对象,从properties中获取EnableAutoConfiguration.class对应的值,然后把它们添加在容器中
-
4、SpringBoot项目的一些配置工作
- SpringBoot启动会加载大量的自动配置类
- 看SpringBoot中有没有我们需要的配置类
- 再来看自动配置类中配置了哪些组件
- 给容器中自动配置类添加组件的时候,会从properties类中获取属性
5、@Conditional注解的作用
- 这个注解及其他派生注解:
- 必须是这个注解指定的条件成立,才给容器添加组件,配置类里的内容才会生效。
-
springboot的自动配置原理
2021-01-14 20:32:541.springboot自动配置的原理 (1)springboot自动配置的核心注解是@SpringBootApplication,该注解是soringboot的启动类注解,他是一个复合注解,里面包含@SpringBootConfiguration和@EnableAutoConfiguration (2)...1.springboot自动配置的原理
(1)springboot自动配置的核心注解是@SpringBootApplication,该注解是soringboot的启动类注解,他是一个复合注解,里面包含@SpringBootConfiguration和@EnableAutoConfiguration
(2)@SpringBootConfiguration:该注解上有一个@Configuration注解,表示这个springboot启动类是一个配置类,将这个类注入到spring容器中
(3)@EnableAutoConfiguration:表示开启自动配置,它也是一个复合注解,里面包含@AutoConfiguration和@Import(AutoConfigurationImportSelector.class)
@AutoConfigurationPackage,该注解上有一个@Import(AutoConfigurationPackages.Registrar.class)注解,其中 Registrar 类的作用是将启动类所在包下的所有子包的内容扫描注入到spring容器中。、(4)@Import(AutoConfigurationImportSelector.class):其中AutoConfigurationImportSelector类中有一个getCandidateConfigurations()方法,该方法通过SpringFactoriesLoader.loadFactoryNames()方法查找位于META-INF/spring.factories文件中的所有自动配置类,并加载这些类。
(5)spring.factories文件是以key-value键值对的形式存储文件里,其中有一个key=EnableAutoConfiguration,它对应的value值就是一个个以AutoConfiguration结尾来命名的 xxxAutoConfiguration 自动配置类。
(6)所以spring boot在整个的启动过程中,其实就是在类路径的META-INF/spring.factories 文件中找到EnableAutoConfiguration对应的所有的自动配置类,然后将所有自动配置类加载到spring容器中。
所有自动配置类都是以AutoConfiguration结尾来命名的,而诸多的xxxAutoConfiguration 其实就是Spring容器的JavaConfig形式,它的作用就是为Spring容器导入bean。
总结springboot如何处理异常的
有模板引擎的情况该将错误页面命名为错误状态码.html放在模板引擎文件夹里面的error文件夹下,发生此状态码的错误就会来到 对应的页面。没有模板引擎(模板引擎找不到这个错误页面),静态资源文件夹下找(也就是static文件夹)
以上都没有错误页面,就是默认来到SpringBoot默认的错误提示页面
在springboot中,如何使用拦截器?
1.继承WebMvcConfigureAdapter类,覆盖其addInterceptors接口,注册我们自定义的拦截器
实现HandlerInterceptor接口,重写接口中的三个方法.注册拦截器. -
springBoot的自动配置原理
2019-11-02 14:22:54自动配置原理: 1)、SpringBoot启动的时候加载主配置类,@EnableAutoConfiguration开启了自动配置功能 2)、@EnableAutoConfiguration 作用: 利用EnableAutoConfigurationImportSelector给容器中导入一些组件? ...自动配置原理:
1)、SpringBoot启动的时候加载主配置类,
@EnableAutoConfiguration
开启了自动配置功能2)、@EnableAutoConfiguration 作用:
-
利用EnableAutoConfigurationImportSelector给容器中导入一些组件?
-
可以查看selectImports()方法的内容;
-
List configurations = getCandidateConfigurations(annotationMetadata, attributes);获取候选的配置
SpringFactoriesLoader.loadFactoryNames() 扫描所有jar包类路径下 META-INF/spring.factories 把扫描到的这些文件的内容包装成properties对象 从properties中获取到EnableAutoConfiguration.class类(类名)对应的值,添加在容器中
将 类路径下 META-INF/spring.factories 里面配置的所有EnableAutoConfiguration的值加入到了容器中;
#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,\ org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\ org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,\ org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\ org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\ org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\ org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\ org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\ org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration
3)、每一个自动配置类进行自动配置功能;
4)、以**HttpEncodingAutoConfiguration(Http编码自动配置)**为例解释自动配置原理;
@Configuration //表示这是一个配置类,以前编写的配置文件一样,也可以给容器中添加组件 @EnableConfigurationProperties(HttpEncodingProperties.class) //启动指定类的ConfigurationProperties功能;将配置文件中对应的值和HttpEncodingProperties绑定起来;并把HttpEncodingProperties加入到ioc容器中 @ConditionalOnWebApplication //Spring底层@Conditional注解(Spring注解版),根据不同的条件,如果满足指定的条件,整个配置类里面的配置就会生效; 判断当前应用是否是web应用,如果是,当前配置类生效 @ConditionalOnClass(CharacterEncodingFilter.class) //判断当前项目有没有这个类CharacterEncodingFilter;SpringMVC中进行乱码解决的过滤器; @ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true) //判断配置文件中是否存在某个配置 spring.http.encoding.enabled;如果不存在,判断也是成立的 //即使我们配置文件中不配置pring.http.encoding.enabled=true,也是默认生效的; public class HttpEncodingAutoConfiguration { //他已经和SpringBoot的配置文件映射了 private final HttpEncodingProperties properties; //只有一个有参构造器的情况下,参数的值就会从容器中拿 public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) { this.properties = properties; } @Bean //给容器中添加一个组件,这个组件的某些值需要从properties中获取 @ConditionalOnMissingBean(CharacterEncodingFilter.class) //判断容器没有这个组件? public CharacterEncodingFilter characterEncodingFilter() { CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter(); filter.setEncoding(this.properties.getCharset().name()); filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST)); filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE)); return filter; }
根据当前不同的条件判断,决定这个配置类是否生效?
一但这个配置类生效;这个配置类就会给容器中添加各种组件;这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的;
5)、所有在配置文件中能配置的属性都是在xxxxProperties类中封装者‘;配置文件能配置什么就可以参照某个功能对应的这个属性类
@ConfigurationProperties(prefix = "spring.http.encoding") //从配置文件中获取指定的值和bean的属性进行绑定 public class HttpEncodingProperties { public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
精髓:
1)、SpringBoot启动会加载大量的自动配置类
2)、我们看我们需要的功能有没有SpringBoot默认写好的自动配置类;
3)、我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件有,我们就不需要再来配置了)
4)、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们就可以在配置文件中指定这些属性的值;
xxxxAutoConfigurartion:自动配置类;
给容器中添加组件
xxxxProperties:封装配置文件中相关属性;
@Conditional 派生注解详解
-