一、前语

大部分的装备都能够用Java类+注解来替代,而在SpringBoot项目中见的最多的莫过于@SpringBootApplication注解了,它在每个SpringBoot的建议类上都有标明。

这个java怎样读注解对SpringBoot的建议和主动装备到底有什么样的springboot面试题影响呢?本文将为各位大佬解析它的源码,揭开@SpringBootApplication注解奥秘的面纱。

二、正文

对SpringBoot工程的主动装备很感喜好,所以学习其java面试题源码并整理了其间一些内容,假设有差错请我们纠正~话不多说,直接上源码;

@SpringBootApplication注解的源码如下:

@Target(ElementType.TYPjavascriptE)
@Retention(RetentionPolicy.R源码集市UNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class)app装置下载,
@Filter(type = FilterTspring结构ype.CUSTOM, classes = AutoConfigurationExcludeFiJavalter.class) })
public @interface SpringBootApplication {
...
}

能够看到这是一个复合注解,总共包括7个不同的注解,下面临spring面试题这7个不同的注解进行剖析。

2.1 注解

2.1.1 注解1:@Target({ElementType.TYPE})

用来标明注解作用规划,TYPE标java言语明效数组函数的使用办法果规源码编程划为类或接口数组的界说

奥秘又强壮的@SpringBootApplication注解

2.1.2 注解2:@Retentio源码编辑器编程猫下载n(RetentionPolicy.RUNTIME)

奥秘又强壮的@SpringBootApplication注解

2.1.3 注解3:@Documented

appear明这个注释是由 javadoc记载的。

2.1.4 注解4:@Inherited

放在注解上,当父类加了@SpringBootApplication注解时,子类也会承继这个注解(对接口的结束类无效)。源码共享网

2.1.5 注解5:@SpringBootCon数组函数的使用办法figuration

底层仍是@Configuration源码共享网注解, 源码如下:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}

2.app装置下载1.6 注解6:@ComappearanceponetSca数组排序n

@ComponenAPPtScan这个注解在Spring中很重要,数组词它对应XML装备中的元源码编辑器手机版下载素@ComponentScan的功用其实便是主动扫描并加载契合条件的组件(比如@Comp源码集市ojavaeenent和@Repository等)或许bean界说,最终将这些bean界说数组c言语加载到IoC容器中。

能够经过basePackages等特点来细粒度的定制@ComponentScan主动扫描的规划,假设不指定,则默许Sprin源码集市g结构结束会从声明@ComponentScanSpring地址类的package进行扫描。所以Sprspringboot常用注解ingBoot的建议类最好是放在root package下,由于默许不指定basePacka数组c言语ges。

2.2 注解:数组词@EnableAutoCappstoreonfigjavaeeuration

个人感觉@EnableAut源码本钱oConfiguration这个Annotation最为重要它的作用能够归纳为:凭借@Import的帮助,将悉数契合主动装备条件的bean定springcloud五大组件义加载到IoC容器。

其源码如下:

@Targ数组的界说et(appreciateElementType.TYP数组公式E)
@Retention(RetentionPolicyapprove.RU数组和链表的差异NspringcloudTIME)
@Documented
@Inappearherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelecappearancetor.class)
public @approveinterface Ena源码编辑器bleAutoConfiguration {
Strinappearanceg ENABLED_OVERRIDE_PROPERTY = "spring.boJavaot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName源码年代() default数组初始化 {};
}

这里需求重视@AutoConfigappearurationPackage和@Import(AutoCspring是什么意思onfispringbootgurationImportSelector.class)两个注解。

2.2.1 注释:@数组词AutoConfigurationPjava环境变量装备ackage

源码如下:

@Target(ElementType.TYPE)
@springboot常用注解Retention(RetentionP源码年代olicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.数组class)
public @intejava环境变量装备rface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] eapprovexcludeNamapplicatione() default {};
}

能够发现这个注解的中心其实也是Import注解,标明关于标明该注解的类的包,应当运用AutoConfigurationPackages注册。接着看Registrar这个类:

sta数组的界说tic class Registrar implements ImportBeanDefinitionRegistrar, Dejava面试题terminableImports {
​
@Ospring面试题verride
//metadata是我们注解源码编辑器编程猫下载地址的元信息源码编辑器手机版下载
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegijava面试题stry registry) {
//将我们注解地址包下悉数的组件进行注册
registerjava环境变量装备(registryAPP, new PackageImport(metadata)javascript.getPackageName());
}
​
@Override
public Set<Object> determineImports(Annspring是什么意思otationMetadata metadata) {
return Coll数组词ections.singleton(new PackageImport(metadata));
}
}

这个类中springmvc的作业原理的中心办法是register办法:

private static final String BEAN = AutoConfigurationPackages.class.getName();
public static void register(BeanDefinitionR数组c言语egistry registry, String... packageNames) {
if (registry.containsBeanDefinition(BEAN)) {
BSpringeanDefinition beanDefinition = registry.getBeanDefin源码编辑器ition(BEAN);
Cojava根底知识点nstructspringboot面试题orArgumentVal数组词ues constructorArguments = bean源码编辑器编程猫下载Definition.getCo数组初始化nstructorArgumentValues();
conjava基本数据类型structorAspring结构rguments.addIndexedArgumentValue(0, addBasePackages(constructorArguments, packageNamjava根底知识点es));
​    }
else {
G数组函数的使用办法enericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(BasePackages数组的界说.class);
beanDefinition.gespring面试题tConstructorArguspringmespringmvc的作业原理ntValues().addIndexedArgumentValue(0, packageNames);
bean数组公式Definition.setRole(BeanDefinition.ROLE_INFRASTRUappearanceCTURE);
reSpringgistry.registerBeanDefin数组函数的使用办法ition(BEAN, beanDefi源码nitijava言语on);
}
}

register办法的逻辑十分明晰:假设这个bean现已被注册,就获取它的结构函数参数值,并将包名添加进去;不然就创立一个新的bean界说数组初始化并进行注册。经过@AutoConfigurationPackage这个注解,能够将注解地址包下悉数javascript的组件进行注册。

2.2.2 注解:@Import(AutoConfigurationImportSelector.class)

这个注解导入了AutoConfiguratioapplicationnImportSelector这个类这个类的中心办法是se数组函数的使用办法lectImports办法,结束ImportSelector接口。办法依据我们在pom.xml文件中装备的jar包和组件进行导入。所源码编辑器以办法回来的是一个Class全途径的String数组,回来的Class会被Spring容器处理。办法源码如下:

@Override
public String[] selectImports(An数组和链表的差异nojava编译器tationMetadata annotationMetadata) {
if (!isEnabled(annotationspringmvc的作业原理Metadata)) {
return NO_IMPORTS;
}
AutoConfig数组和链表的差异urationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.load源码共享网Mspringboot常用注解etapproveadata(this.beanClassLoader);
AutoConfiguraJavationEntry autoConfspring面试题igurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,
annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntrjavascripty.getConfigurations());
}数组和链表的差异

这个办法的结构也很明晰,首要经过isEnabled办法判别是否需求进行导入,假设需求Spring导入的话,经过loadMetadata办法获取装备信息,并经过getAutoConfigurationEntry进行自数组排序动装置。isEnabled办法源码如下:

protected boolea源码编辑器编程猫下载n isEnabled(AnnotatappearionMetadata metadata) {
if (getClass() == AutoConfigurationImportSelector.class) {
return getEnvironment().getProper源码编辑器ty(EnableAutoConfiguration.ENABLED_OVERRIDE_PROPERTY, Boolean.class, true);
}
return true;
}

这个办法经过EnableAutoConfiguration.ENABLED_OVERRIDE_PROPERTY这个装备项进行判别是否需java怎样读求主动装备,默java怎样读许为true。loadMetadata办法源码如下:

protected static final String PATH = "META-INF/" + "spring-autoconfigjava面试题ure-metadata.properties";
​
publicspringcloud五大组件 static AutoConfigurationMetadata源码共享网 loadMetadata(ClassLoader classLoader) {
return loadMetadata(classLoader, PATH);
}
​
st源码编辑器手机版下载atic AutoConfigurationMetadata loadMetadata(ClassLoader classLospringmvc的作业原理ader, String path) {
try {
Enumeratiapproachon<URL> urls = (classLoader != null) ? classLoaderappointment.getResources(path)
: ClassLoader.getSystemResources(path);
Projava环境变量装备perties properties = n源码共享网ew Properties();
while (urls.hasMoreElements(数组词)) {
propejava编译器rties.putAll(Prop源码之家ertijava根底知识点esLoaderUtils.loadProperties(new UrlResource(urls.nejavascriptxtElement())));
}
return loadMetadata(java环境变量装备properties);
}
cat源码编辑器编程猫下载ch (IOException ex) {
throw new IllegalArgappearanceumentException("Unaspringble to load @ConditionalOnClas源码之家s location [" + pjavaeeath + "]", ex);
}
}
static AJavautoConfigurationMetadata loadMetadata(Properties properties) {
return new PropertiesAuto数组公式ConfigurationMetadata(properties);
}

能够看到这个办法会加载META-INF/spring-autoconfigure-metadata.properties下的悉数装备信息并包装成Aut数组oConfiappreciategapproveurationMetadata方针回来。

注:spring-autoconfigure-metadata.properties文javascript件在sprijava面试题ng-boot-autoconfigure-2.1.9.RELEASE.jar/META-INF下。

getAutoConfigurationEntryspringboot办法源码如下:

protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,
AnnotatioapproachnMetadata annotationMetadspringbootata) {
if (!isEnabled(annotationMetadata)) {
return EMPT源码编程Y_ENTRY;
}
AnnotationAttributes attributes数组公式 = getAttributes(annotation源码本钱MJavaetadata);
List<String> configurations = getCandidat源码编辑器手机版下载eConfiguratjava编译器ions(annotationMetadata, attributes);
configurations = removeDuplicates(源码编辑器configurations);
Set<String&g数组排序t; exclusions = getExclusspring是什么意思ions(annotationMeta数组指针data, attributes);
checkEx源码编程cludedClasapproveses(configuratiojava编译器ns, exclusions);
configurations.removeAll(exclusions);
configura源码tion源码编程s = filter(configurations, aujava面试题toConfigurationMetadata);
fireAutoConfigurapp装置下载ationI源码编辑器手机版下载mportEvents(c源码本钱onfigurations, exclusions);
return new AutoC源码年代onfigurationEJavantry(configurations, exclusspringmvc的作业原理ions);
}

这个办法是AutoConfiguration的主流程办法,能够将这个办法的每一行看做一个过程,那么处理过程如下:

1.加载装备了@EnableAutoConfig源码集市uration注解的特点值getAttribute办法:

protected AnnotationAttributes getAttributes(AnnotationMetadata metadata) {
String name = getAnnotationClaappless().getNaappearme();
AnnotationAttributes attributes = Annotationjava模拟器Attributes.fromMap(mappreciateetadata.getAnnotationAttrispringbutes(name, true));
Assert.notNull(attributespring结构s, () -> "No auto-configuration attributes found. Ijavascripts " + metadata.getClassNamespring结构()
+ " annotated with " + ClassUjava模拟器tils.getShortName(name) + "?");
return attributes;
}

2.得到META-INF/spring.factorieappears文件中以@Ejava根底知识点nableAutoConfiguration完全限源码编辑器手机版下载制类名做key的vaapprovelue,getCandidateConfigurations办法:

protected List<String> getCandidateConfigurspringations(AnnotationMetadata metadata, AnnotationAttributes attrspring结构ibutes) {
List<Stappstorering> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactor源码年代iesLoaderFjava模拟器actoryClass(),
getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
+ "are using a custom packaging, make sure that f数组初始化il数组去重e is correct.");
return configurations;
}
protected Class&l源码t;?> getSpringFactoriesLoaderFactoryClass() {
return EnableAutoConfiguration.class;
}

其间,SpringFactoriesLoaappearanceder.loadFactoryNames()这个办法的作用是运数组用给定的类加载器从META-INF/spring.factories加载给定类型的工厂结束的完全约束类名;

3.去重;

4.得到需求java怎样读清扫的类的类名,这些数组和链表的差异类能够在@EnableAutspringoConfiguration注解中装备;

5.检查Spring这两个集结;

6.把需求清扫的类移除;

7.依据OnBeanCondition、OnClassCondition等条件进行过滤(有喜好能够深化了解);

8.广播作业,得到AutoConfigurationImportListener悉数结束类,然后生成作业进行广播;

9.把需求装置和打app装置下载扫的类数组完全约束名封装成了Ajava面试题utoConfig数组函数的使用办法urationEntry方针回来。

因此,@EnableAutoappstoreConfiguration能够简略总结为:从classpath中搜索悉数的META-INF/spring.factoriesAPP装备文件,并将其间EnableAutoConfiguration对应的装备项经过反射实例化为数组函数的使用办法对应的标明了@Configuration的IoC容器装备类,并加载到IoC容器。

三、小结

经过以上剖析可知@SpringBootApspringbootplic数组初始化ation注解的运作是经过@SpringApplicationConfiguration声明被标明类为装备类,然后被AnnotationConfigAppSpringlicationContext扫描并初始化Spring容器。

经过@EnableAutoapplicationConfiguration来扫描,过滤并加载所需求的组件;经过@ComponentScan扫描并注册悉数标明了@Componejavaeent及其子注解的数组指针类;这些注解的一起运作结束了springbojava编译器ot工程强壮的主动装备才干。

以上便是本次总结的悉数内容,期望能对我们有所帮助。假设有遗漏差错之处,还请我们数组指针不吝纠正。源码年代

作者:vspringivo互联网开发数组函数的使用办法团队-Peng peng