springboot如何实现自动装配源码解读

作者:码上代码 时间:2023-11-10 15:44:20 

Spring Boot 自动装配

最重要的注解@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 {

@AliasFor(annotation = EnableAutoConfiguration.class)
Class<?>[] exclude() default {};

@AliasFor(annotation = EnableAutoConfiguration.class)
String[] excludeName() default {};

@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};

@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
Class<?>[] scanBasePackageClasses() default {};

@AliasFor(annotation = Configuration.class)
boolean proxyBeanMethods() default true;

}

EnableAutoConfiguration

是实现自动装配的核心注解


@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

}

getAutoConfigurationMetadata()


@Override
public void process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) {
Assert.state(deferredImportSelector instanceof AutoConfigurationImportSelector,
() -> String.format("Only %s implementations are supported, got %s",
AutoConfigurationImportSelector.class.getSimpleName(),
deferredImportSelector.getClass().getName()));
AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector) deferredImportSelector)
.getAutoConfigurationEntry(
// 加载配置元数据
getAutoConfigurationMetadata(), annotationMetadata);
this.autoConfigurationEntries.add(autoConfigurationEntry);
for (String importClassName : autoConfigurationEntry.getConfigurations()) {
this.entries.putIfAbsent(importClassName, annotationMetadata);
}
}

private AutoConfigurationMetadata getAutoConfigurationMetadata() {
if (this.autoConfigurationMetadata == null) {
// 加载配置信息
this.autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
}
return this.autoConfigurationMetadata;
}
static AutoConfigurationMetadata loadMetadata(ClassLoader classLoader, String path) {
try {

// 获取资源路径
Enumeration<URL> urls = (classLoader != null) ? classLoader.getResources(path)
: ClassLoader.getSystemResources(path);
Properties properties = new Properties();
while (urls.hasMoreElements()) {
properties.putAll(PropertiesLoaderUtils.loadProperties(new UrlResource(urls.nextElement())));
}
return loadMetadata(properties);
}
catch (IOException ex) {
throw new IllegalArgumentException("Unable to load @ConditionalOnClass location [" + path + "]", ex);
}
}

protected static final String PATH = "META-INF/spring-autoconfigure-metadata.properties";

注意: 这个文件在target编译后的文件夹中
自动装配

spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories

该文件内存有:

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,\

EnableConfigurationProperties


@ConfigurationProperties(prefix = "spring.redis")
public class RedisProperties {

/**
* Database index used by the connection factory.
*/
private int database = 0;

/**
* Connection URL. Overrides host, port, and password. User is ignored. Example:
* redis://user:password@example.com:6379
*/
private String url;

/**
* Redis server host.
*/
private String host = "localhost";

/**
* Login password of the redis server.
*/
private String password;

/**
* Redis server port.
*/
private int port = 6379;

/**
* Whether to enable SSL support.
*/
private boolean ssl;

/**
* Connection timeout.
*/
private Duration timeout;

/**
* Client name to be set on connections with CLIENT SETNAME.
*/
private String clientName;

}

希望通过本篇对于springboot自动装配的解读,让大家对springboot底层有了一个大致了解,只分析了主要方法,希望对大家有帮助

来源:https://blog.csdn.net/weixin_44302240/article/details/110630566

标签:springboot,自动装配
0
投稿

猜你喜欢

  • Java 实战项目之疫情人员流动管理系统详解

    2022-08-04 19:30:57
  • Android 中ScrollView与ListView冲突问题的解决办法

    2022-06-15 04:31:46
  • Spring存储与读取Bean对象方法

    2021-11-12 03:35:27
  • Android SharedPreferences实现记住密码和自动登录界面

    2023-06-15 20:07:00
  • Spring AOP面向切面编程实现原理方法详解

    2021-07-22 00:26:07
  • Java泛型的使用限制实例分析

    2023-05-07 20:14:52
  • 浅析Android 的 MediaPlayer类

    2021-06-01 01:50:08
  • java排查一个线上死循环cpu暴涨的过程分析

    2022-07-20 01:27:08
  • Java编程枚举类实战代码分享

    2023-10-16 09:36:51
  • struts2 validation.xml 验证规则代码解析

    2021-09-14 22:01:27
  • Android-Service实现手机壁纸自动更换

    2022-05-21 23:15:35
  • 详解微信开发之access_token之坑

    2022-09-04 16:49:30
  • Java如何基于command调用openssl生成私钥证书

    2023-08-09 11:55:39
  • 解答“60k”大佬的19道C#面试题(下)

    2022-10-07 22:31:10
  • Android 客户端RSA加密的实现方法

    2023-05-23 13:50:43
  • SpringBoot如何用java生成静态html

    2023-08-08 08:46:59
  • C# 实现绘制PDF嵌套表格案例详解

    2023-05-25 11:57:13
  • C#使用Unity实现剪刀石头布游戏

    2023-03-01 06:30:18
  • VS Code开发React-Native及Flutter 开启无线局域网安卓真机调试问题

    2022-04-05 18:32:06
  • 详谈hibernate,jpa与spring data jpa三者之间的关系

    2022-08-04 22:35:57
  • asp之家 软件编程 m.aspxhome.com