springboot-注解汇总,招银网络java面试

@ConfigurationProperties(prefix = “spring.datasource”)

public class DataSourceProperties implements BeanClassLoaderAware, InitializingBean {

private ClassLoader classLoader;

private String name;

private boolean generateUniqueName;

private Class type;

private String driverClassName;

private String url;

private String username;

private String password;

private String jndiName;

。。。

}

配置文件中的属性:

spring:

datasource:

driver-class-name:

url:

password:

username:

前缀+属性名称,如果可以对应上配置文件中的key,就把key对应的value,赋值给bean的属性。这个注解可以单独使用,但你想把这个类放入到容器中,就要搭配@Configuration。注意;这个的搭配和前面两个注解的搭配不一样。@PropertySource,@ComponentScans,如果不和@Configuration注解一起使用,那么其功能就不能实现。而@ConfigurationProperties注解,搭配@Configuration的目的仅仅是将其放入到容器中。如果单独使用功能是可以实现的。 为了方便,springboot还提供了一个注解,EnableConfigurationProperties,这个注解可以将配置的属性bean放入的容器中。

@EnableConfigurationProperties


这个注解可以把属性bean放入到容器中,将处理ConfigurationProperties注解的逻辑类放入到容器中。

使用方法

@EnableConfigurationProperties(JdbcProperties.class)

public class JdbcTemplateAutoConfiguration {

原理

直接看EnableConfigurationPropertiesImportSelector

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Import(EnableConfigurationPropertiesImportSelector.class)

public @interface EnableConfigurationProperties {

org.springframework.boot.context.properties.EnableConfigurationPropertiesImportSelector

实现了ImportSelector接口,直接看selectImports方法

private static final String[] IMPORTS = {

ConfigurationPropertiesBeanRegistrar.class.getName(),

ConfigurationPropertiesBindingPostProcessorRegistrar.class.getName() };

@Override

public String[] selectImports(AnnotationMetadata metadata) {

return IMPORTS;

}

返回了两个类ConfigurationPropertiesBeanRegistrar是将配置的属性bean放入到容器。ConfigurationPropertiesBindingPostProcessorRegistrar是处理ConfigurationProperties注解的,绑定逻辑。这两个类的逻辑自己看就可以了,了解大概流程。

@NestedConfigurationProperty


这个注解还是和属性相关,是嵌套类型的。使用方法使用方法,解析的逻辑应该还是在ConfigurationPropertiesBindingPostProcessorRegistrar类中。

@ImportResource


这个类是加载配置文件的,没有springboot之前,使用spring的时候要有spring.xml的文件,在里面陪各种信息。这个注解就是加载xml配置文件的。

下面重点分析条件注解

AutoConfigureBefore、AutoConfigureAfter、AutoConfigureOrder


在自动配置的时候,会找到这三个注解,注意,这三个注解是springboot自动配置专用的注解,我们开发的时候是用不上的。主要功能就是区分解析的的顺序,

org.springframework.context.annotation.ConfigurationClassParser.DeferredImportSelectorGroupingHandler#processGroupImports

public void processGroupImports() {

for (DeferredImportSelectorGrouping grouping : this.groupings.values()) {

Predicate exclusionFilter = grouping.getCandidateFilter();

// 得到所有的配置类,之后遍历

grouping.getImports().forEach(entry -> {

ConfigurationClass configurationClass = this.configurationClasses.get(entry.getMetadata());

try {

// 分别调用processImports,走导入类的逻辑。

processImports(configurationClass, asSourceClass(configurationClass, exclusionFilter),

Collections.singleton(asSourceClass(entry.getImportClassName(), exclusionFilter)),

exclusionFilter, false);

}

catch (BeanDefinitionStoreException ex) {

throw ex;

}

catch (Throwable ex) {

throw new BeanDefinitionStoreException(

“Failed to process import candidates for configuration class [” +

configurationClass.getMetadata().getClassName() + “]”, ex);

}

});

}

}

下面看看grouping.getImports()方法做了什么操作。

public Iterable getImports() {

for (DeferredImportSelectorHolder deferredImport : this.deferredImports) {

// 这块是从配置文件中读取出配置类(注意,这里的配置类是过滤之后的,过滤逻辑可以可以自己看看),

this.group.process(deferredImport.getConfigurationClass().getMetadata(),

deferredImport.getImportSelector());

}

//

return this.group.selectImports();

}

public Iterable selectImports() {

if (this.autoConfigurationEntries.isEmpty()) {

return Collections.emptyList();

}

Set allExclusions = this.autoConfigurationEntries.stream()

.map(AutoConfigurationEntry::getExclusions).flatMap(Collection::stream).collect(Collectors.toSet());

Set processedConfigurations = this.autoConfigurationEntries.stream()

.map(AutoConfigurationEntry::getConfigurations).flatMap(Collection::stream)

.collect(Collectors.toCollection(LinkedHashSet::new));

processedConfigurations.removeAll(allExclusions);

// 这步,排序了,看看是怎么排序的

return sortAutoConfigurations(processedConfigurations, getAutoConfigurationMetadata()).stream()

.map((importClassName) -> new Entry(this.entries.get(importClassName), importClassName))

.collect(Collectors.toList());

}

List getInPriorityOrder(Collection classNames) {

AutoConfigurationClasses classes = new AutoConfigurationClasses(this.metadataReaderFactory,

this.autoConfigurationMetadata, classNames);

List orderedClassNames = new ArrayList<>(classNames);

// 默认是按照字母的顺序

Collections.sort(orderedClassNames);

// 之后再按照order的顺序

orderedClassNames.sort((o1,

《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》

【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享

o2) -> {

int i1 = classes.get(o1).getOrder();

int i2 = classes.get(o2).getOrder();

return Integer.compare(i1, i2);

});

// 之后处理@AutoConfigureBefore @AutoConfigureAfter注解的配置。

orderedClassNames = sortByAnnotation(classes, orderedClassNames);

return orderedClassNames;

}

ConditionalOnClass,ConditionalOnBean,ConditionalOnMissingBean,ConditionalOnMissingClass,ConditionalOnProperty


你可能感兴趣的:(程序员,面试,java,后端)