springboot框架介绍(⾃动配置)
springboot框架介绍
Spring简介
在了解Springboot前, 我们先简单了解下Spring.
Spring是⼀个开源框架,Spring是于2003 年兴起的⼀个轻量级的Java 开发框架。它是为了解决企业应⽤开发的复杂性⽽创建的。框架的主要优势之⼀就是其分层架构. Spring的⽤途不仅限于服务器端的开发。从简单性、可测试性和松耦合的⾓度⽽⾔,任何Java应⽤都可以从Spring中受益。Spring的核⼼是控制反转(IoC)和⾯向切⾯(AOP)。简单来说,Spring是⼀个分层的JavaSE/EE full-stack(⼀站式) 轻量级开源框架。
什么是Spring Boot
Spring Boot是Spring 为了简化Spring Web开发设计的⼀个全新框架, 和传统的Spring MVC相⽐,增加了开发效率,该框架使⽤了特定的⽅式来进⾏配置,从⽽使开发⼈员不再需要定义样板化的配置; 做到开箱即⽤. 可以⾮常快速地新建⼀个项⽬; ⼤家都知道 "boot"是启动的意思, 所以springboot简单来讲就是⼀个启动Spring项⽬的⼯具;
SpringBoot特性
1.⾃动装配
Spring Boot⾃动配置,就是程序需要什么装配什么。⽐如当程序的pom⽂件引⼊了Redis的起步依赖,Spring Boot就会在程序中⾃动引⼊默认的Redis的配置RedisTemplate
2.起步依赖
传统的开发过程中,向项⽬添加依赖常常会选择版本,解决版本冲突,⼗分耗费精⼒。⽽使⽤Spring Boot的起步依赖,只需要加⼊Spring-boot-starter-web的依赖,便会⾃动引⼊Spring MVC功能的相关依赖.
3.Actuator对运⾏状态监控
Spring Boot提供了Actuator组件,并提供了程序运⾏状态的监控功能,这种设计可以让开发⼈员能够知道注⼊了哪些Bean,它们的运⾏状态是怎么样的.
以上就是Springboot简单的介绍. 下⾯我们来深⼊了解下他⾃动装配的特性
Springboot ⾃动装配
Springboot ⾃动装配需要依赖注解来完成
1. @SpringBootApplication注解
⾸先从@SpringBootApplication 作为⼊⼝来看下这个复合注解;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters ={@Filter(
type = FilterType.CUSTOM,
classes ={TypeExcludeFilter.class}
),@Filter(
type = FilterType.CUSTOM,
classes ={AutoConfigurationExcludeFilter.class}
)}
)
public@interface SpringBootApplication {}
1.1 @SpringBootConfiguration
此注解⽐较简单,表明该类是⼀个Spring的配置类,也作为Spring⼀个组件
1.2 @ComponentScan
⽤于类或接⼝上主要是指定扫描路径,Spring会把指定路径下带有指定注解的类⾃动装配到bean容器⾥。会被⾃动装配的注解包括@Controller、@Service、@Component、@Repository等等。
1.3 ⾃动装配灵魂注解—@EnableAutoConfiguration
我们先进⼊@EnableAutoConfiguration注解看⼀下源码
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public@interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY ="ableautoconfiguration";
Class<?>[]exclude()default{};
String[]excludeName()default{};
}
除去⼀些元注解,我们看到还有两个注解
1. @AutoConfigurationPackage
它是负责保存标注相关注解的类的所在包路径。使⽤⼀个BasePackage类,保存这个路径。然后使⽤@Import注解将其注⼊到ioc容器中。这样,可以在容器中拿到该路径。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({Registrar.class})
public@interface AutoConfigurationPackage {
String[]basePackages()default{};
Class<?>[]basePackageClasses()default{};
}
再来看⼀下 Registrar.class类, 它是⼀个静态内部类
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
Registrar(){
}
// 注册初始化Bean定义,获取packageNames
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry){
orts(metadata)).getPackageNames().toArray( new String[0]));
}
}
其实就是注册了autoConfigurationPackages这个名字的bean。
现在包扫描路径获取到了,那具体加载哪些组件呢,看看下⾯这个重点注解
@Import({AutoConfigurationImportSelector.class})
@Import注解就是给Spring容器中导⼊⼀些组件,这⾥传⼊了⼀个组件的选择器:AutoConfigurationImportSelector
AutoConfigurationImportSelector类中 selectImports⽅法
// 选择导⼊的组件,返回组件路径
public String[]selectImports(AnnotationMetadata annotationMetadata){
// 判断是否禁⽌⾃动导⼊
if(!this.isEnabled(annotationMetadata)){
return NO_IMPORTS;
}else{
// 获取⾃动导⼊配置
AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry =AutoConfigurationEntry(annotationMetadata);
Configurations());
}
}
在往下看 AutoConfigurationEntry(annotationMetadata) 这个⽅法源码
protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata){ if(!this.isEnabled(annotationM
etadata)){
return EMPTY_ENTRY;
}else{
AnnotationAttributes attributes =Attributes(annotationMetadata);
/**
* 获取所有候选配置类EnableAutoConfiguration
*/
List<String> configurations =CandidateConfigurations(annotationMetadata, attributes);
configurations =veDuplicates(configurations);
Set<String> exclusions =Exclusions(annotationMetadata, attributes);
this.checkExcludedClasses(configurations, exclusions);
configurations =ConfigurationClassFilter().filter(configurations);
this.fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
}
}
在看源码 CandidateConfigurations(annotationMetadata, attributes)这个⽅法
/**
* 获取所有候选配置类EnableAutoConfiguration
* 使⽤了内部⼯具使⽤SpringFactoriesLoader,查classpath上所有jar包中的
* META-INF\spring.factories,出其中key为
* org.springframework.boot.autoconfigure.EnableAutoConfiguration
* 的属性定义的⼯⼚类名称。
* 虽然参数有annotationMetadata,attributes,但在 AutoConfigurationImportSelector 的
* 实现 getCandidateConfigurations()中,这两个参数并未使⽤
* 返回应该被⾃动配置的类名称
*/
protected List<String>getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes){
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
getBeanClassLoader());
you "
+"are using a custom packaging, make sure that file is correct.");
return configurations;
}
/**
* 查看上⾯的调⽤⽅法 loadFactoryNames()
*/
public static List<String>loadFactoryNames(Class<?> factoryType,@Nullable ClassLoader classLoader){
String factoryTypeName = Name();
springboot aopreturn(List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, ptyList());
}
/**
* 查看上⾯的调⽤⽅法 loadSpringFactories() 加载spring.factories
*/
private static Map<String, List<String>>loadSpringFactories(@Nullable ClassLoader classLoader){
MultiValueMap<String, String> result =((classLoader);
if(result !=null){
return result;
}else{
try{
Enumeration<URL> urls = classLoader !=null? Resources("META-INF/spring.factories"): SystemResources("ME TA-INF/spring.factories");
LinkedMultiValueMap result =new LinkedMultiValueMap();
// ...省略部分代码
cache.put(classLoader, result);
return result;
}catch(IOException var13){
throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13);
}
}
}
主要就是看类加载器加载 spring.factories配置. 这个配置有什么特别之处呢?
我们选择Redission.jar包, 在来看下 META-INF/spring.factories⾥⾯是什么:
org.springframework.boot.autoconfigure.disson.spring.cache.RedissonCacheStatisticsAutoConfiguration
RedissonCacheStatisticsAutoConfiguration 源码
@Configuration
@AutoConfigureAfter({CacheAutoConfiguration.class})
@ConditionalOnBean({CacheManager.class})
@ConditionalOnClass({MeterBinder.class})
public class RedissonCacheStatisticsAutoConfiguration {
public RedissonCacheStatisticsAutoConfiguration(){
}
@Bean
public RedissonCacheMeterBinderProvider redissonCacheMeterBinderProvider(){
return new RedissonCacheMeterBinderProvider();
}
}
解析到这⾥, 我们应该⼤概明⽩springboot⾃动装配是怎么样的流程了, Spring Boot在启动的时候从类路径下的META-
INF/spring.factories中获取EnableAutoConfiguration指定的值,将这些值作为⾃动配置类导⼊到容器中,⾃动配置类就⽣效,这些⾃动配置类都是以AutoConfiguration结尾来命名的, 它实际上就是⼀个JavaConfig形式的IOC容器配置类,
参考⽂章:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论