SpringBoot自动装配源码解析

运行原理

在第一次使用spring boot的时候,大家都会惊讶于@SpringBootApplication这个注解,有了它马上就能够让整个应用跑起来。实际上它只是一个组合注解,包含@Configuration、@EnableAutoConfiguration、@ComponentScan这三个注解。

123456789101112131415161718192021

@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@Configuration@EnableAutoConfiguration@ComponentScanpublic@interfaceSpringBootApplication{ Class<?>[] exclude() default{}; String[] excludeName() default{}; @AliasFor( annotation = ComponentScan.class, attribute = "basePackages" ) String[] scanBasePackages() default{}; @AliasFor( annotation = ComponentScan.class, attribute = "basePackageClasses" ) Class<?>[] scanBasePackageClasses() default{};}

21

它的核心功能是由@EnableAutoConfiguration这个注解提供的,我们来看看@EnableAutoConfiguration的源代码:

123456789101112

@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@AutoConfigurationPackage@Import({EnableAutoConfigurationImportSelector.class})public@interfaceEnableAutoConfiguration{ Class<?>[] exclude() default{}; String[] excludeName() default{};}10

这里的关键功能是@Import注解导入的配置功能

EnableAutoConfigurationImportSelector使用SpringFactoriesLoader.loadFactoryNames方法来扫描具有META-INF/spring.factories文件的jar包,spring-boot-autoconfigure-x.x.x.x.jar里就有一个spring.factories文件,这个文件中声明了有哪些要自动配置。

下面我们来分析一下spring boot autoconfigure里面的MongoAutoConfiguration(mongodb的自动配置),相信你就会明白这套自动配置机制到底是怎么一回事儿:

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950

//// Source code recreated from a .class file by IntelliJ IDEA// (powered by Fernflower decompiler)//packageorg.springframework.boot.autoconfigure.mongo;importcom.mongodb.MongoClient;importcom.mongodb.MongoClientOptions;importjava.net.UnknownHostException;importjavax.annotation.PreDestroy;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.boot.autoconfigure.condition.ConditionalOnClass;importorg.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;importorg.springframework.boot.autoconfigure.mongo.MongoProperties;importorg.springframework.boot.context.properties.EnableConfigurationProperties;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.core.env.Environment;@Configuration@ConditionalOnClass({MongoClient.class}) @EnableConfigurationProperties({MongoProperties.class}) //开启属性注入。@ConditionalOnMissingBean( type = {"org.springframework.data.mongodb.MongoDbFactory"})publicclassMongoAutoConfiguration{ @Autowired privateMongoProperties properties; @Autowired( required = false ) privateMongoClientOptions options; @Autowired privateEnvironment environment; privateMongoClient mongo; publicMongoAutoConfiguration() { } @PreDestroy publicvoidclose() { if(this.mongo != null) { this.mongo.close(); } } @Bean//使用java配置,当容器中没有这个bean的时候执行初始化 @ConditionalOnMissingBean publicMongoClient mongo() throwsUnknownHostException { this.mongo = this.properties.createMongoClient(this.options, this.environment); returnthis.mongo; }}48

首先这被@Configuration注解了,是一个配置类,当满足以下条件这个bean被装配:

  • 当MongoClient在类路径下。
  • 当容器中没有org.springframework.data.mongodb.MongoDbFactory这类bean的时候。

此外,我们可以看一下通过@EnableConfigurationProperties({MongoProperties.class}) 自动注入的属性(这是习惯优于配置的最终落地点):

12345678910111213141516171819

@ConfigurationProperties( prefix = "spring.data.mongodb")publicclassMongoProperties{ publicstaticfinalintDEFAULT\_PORT = 27017; privateString host; privateInteger port = null; privateString uri = "mongodb://localhost/test"; privateString database; privateString authenticationDatabase; privateString gridFsDatabase; privateString username; privatechar[] password; privateClass<?> fieldNamingStrategy;......}17

所以在我们什么都不干的情况下,只需要引入spring-data-mongodb这个依赖再加上默认的MongoDB server我们就能够快速集成MongoDB,用MongodbTemplate访问数据库。

同时我们可以通过在application.yaml中修改spring.data.mongodb相关的参数就能够修改连接配置,如:

12345678

spring: data: mongodb: host: localhost port: 27017 username: chingzhu password: test123 database: icekredit

8

利用这套原理,我们也可以轻松地把目前spring boot还未集成的、我们自己要使用的第三方技术自动集成起来。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏刘望舒

Android深入四大组件(七)Android8.0 根Activity启动过程(后篇)

前言 在几个月前我写了Android深入四大组件(一)应用程序启动过程这篇文章,它是基于Android 7.0的,当我开始阅读Android 8.0源码时发现应...

289100
来自专栏技术博文

php QR Code二维码生成类

<?php /* * PHP QR Code encoder * * This file contains MERGED version of PHP ...

41950
来自专栏Kubernetes

Controlling Access to the Kubernetes API

? API Server Ports and IPs By default the Kubernetes API server serves HTTP o...

30180
来自专栏ImportSource

Spring5以来注册Bean的各种姿势,特别最后的纯编码注册值得尝试

各位好,今天我们的内容是有关Spring 5以来有关注册bean的几种方式。前面两三个是比较常用的方式,最后两种是只有在特殊的场合下才会被用到和想到。我们会分别...

1.6K70
来自专栏Android干货

Android 针对单个Activity设置状态栏颜色

19950
来自专栏Java后端技术

SpringBoot初体验及原理解析

​  上篇文章,我们聊到了SpringBoot得以实现的幕后推手,这次我们来用SpringBoot开始HelloWorld之旅。SpringBoot是Sprin...

16020
来自专栏有刻

Java 小记 — Spring Boot 注解

390130
来自专栏运维

CentOS6.3 x86_64位安装xfce4桌面vncserver服务

CentOS6.3 x86_64位安装xfce4桌面vncserver服务 注意这里用的是最小化安装纯净系统212个包CentOS-6.3-x86_64-...

18010
来自专栏A周立SpringCloud

使用Spring Cloud Feign上传文件

最近经常有人问Spring Cloud Feign如何上传文件。有团队的新成员,也有其他公司的兄弟。本文简单做个总结—— 早期的Spring Cloud中,Fe...

43190
来自专栏Netkiller

Apache Sqoop 将mysql导入到Hadoop HDFS

第 21 章 Apache Sqoop 目录 21.1. 安装 Sqoop 21.2. sqoop2-tool 21.2.1. verify 21.2.2. u...

63270

扫码关注云+社区

领取腾讯云代金券