1.什么是springboot自动配置:Auto-Configuration
自动配置值得是基于引入依赖的jar包,对springboot应用进行自动配置。自动配置为springboot框架的“开箱即用”特点提供了基础支撑
demo:在springboot中使用mongodb
引入 implementation 'org.springframework.boot:spring-boot-starter-data-mongodb' 配置mongo服務器 data: mongodb: collectionName: table-v2 database: test uri: "mongodb://FID:password@\ hotname/?\ replicaSet=MGORPST_3004&ssl=true&sslInvalidHostNameAllowed=true" 直接使用mongoTemplate或者reactiveMongoTemplate

@Configuration @RequiredArgsConstructor @EnableConfigurationProperties(MongoCommonProperties.class) @Slf4j @Data public class MongoConfig extends AbstractMongoClientConfiguration { private final MongoCommonProperties properties; @Value("${spring.data.mongodb.collectionName}") private String collectionName; @Value("${spring.data.mongodb.collectionName}-payload") private String payloadCollectionName; @Value("${spring.data.mongodb.maxLength}") private Integer maxLength; @Value("${spring.data.mongodb.useGridFs}") private boolean useGridFs; @Override public String getDatabaseName() { return properties.getDatabase(); } private static MongoClient mongoClient = null; @Override public MongoClient mongoClient() { if (mongoClient == null) { String mongoUri = ""; String password = ""; if ("primary".equals(properties.getMongoType())) { mongoUri = properties.getUri(); password = retrievePassword(); } else { mongoUri = properties.getNyuri(); password = new String(properties.getPassword()); if (StringUtils.isEmpty(password)) { return null; } } ConnectionString connectionString = new ConnectionString(mongoUri.replace("password", password)); MongoClientSettings mongoClientSettings = MongoClientSettings.builder().applyConnectionString(connectionString).build(); mongoClient = MongoClients.create(mongoClientSettings); } return mongoClient; } @Primary @Bean(name = "mongoTemplate") public MongoTemplate getMongoTemplate() { if (mongoClient != null) { // close mongo client before recreate, because this will lead memory leak mongoClient.close(); mongoClient = null; } log.info("mongo DB: {}", properties.getDatabase()); MongoDatabaseFactory mongoDbFactory = new SimpleMongoClientDatabaseFactory(mongoClient(), properties.getDatabase()); return new MongoTemplate(mongoDbFactory, getIndexEnabledMongoConverter(mongoDbFactory)); } private static MongoConverter getIndexEnabledMongoConverter(MongoDatabaseFactory factory) { DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory); MongoCustomConversions conversions = new MongoCustomConversions(Collections.emptyList()); MongoMappingContext mappingContext = new MongoMappingContext(); mappingContext.setSimpleTypeHolder(conversions.getSimpleTypeHolder()); mappingContext.afterPropertiesSet(); // This is enable auto index mappingContext.setAutoIndexCreation(true); MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, mappingContext); converter.setCustomConversions(conversions); converter.setCodecRegistryProvider(factory); converter.afterPropertiesSet(); return converter; } /** * Retrieve password from CyberArk * * @return */ public String retrievePassword() { StringBuilder stringBuilder = new StringBuilder(); try { URL pass = new URL(properties.getPasswordURL()); URLConnection yc = pass.openConnection(); String inputLine; try (BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream())); ) { while ((inputLine = in.readLine()) != null) { stringBuilder.append(inputLine); } } } catch (IOException e) { log.error("Failed to retrieve password from {}", properties.getPasswordURL(), e); } return stringBuilder.toString(); } @Bean public GridFsTemplate gridFsTemplate( MongoDatabaseFactory mongoDatabaseFactory, MappingMongoConverter mappingMongoConverter) throws Exception { return new GridFsTemplate(mongoDatabaseFactory, mappingMongoConverter); } @Override public boolean autoIndexCreation() { return true; } }
直接用以上三步就可以在springboot中使用mongo,整個過程springboot自动完成mongo配置,将相关对象注入到IOC容器中 (面试问IOC时候可以从这个角度回答)
2.默认自动配置类
Springboot通过自动配置可以自动加载一些需要的配置信息,引入了一个依赖:spring-boot-autoconfigure,其中定义了大量自动配置类
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
2.自动配置实现原理
@EnableAutoConfiguration:开启SpringBoot的自动配置,并且根据你引入的依赖来生效对应的默认配置(在springboot中不需要手动添加这个注解)
@Conditional :可以标注在类上面,表示该类下面的所有@Bean都会启用配置,也可以标注在方法上面,只是对该方法启用配置。
@ConditionalOnBean(仅仅在当前上下文中存在某个对象时,才会实例化一个Bean)
@ConditionalOnClass(某个class位于类路径上,才会实例化一个Bean)
@ConditionalOnExpression(当表达式为true的时候,才会实例化一个Bean)
@ConditionalOnMissingBean(仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean)
@ConditionalOnMissingClass(某个class类路径上不存在的时候,才会实例化一个Bean)
@ConditionalOnNotWebApplication(不是web应用)
示例代码:
Config类: package com.fql.example.project.autoconfig.config; import com.fql.example.project.autoconfig.service.TestService; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /**https://blog.csdn.net/wolf2s/article/details/122260211 * Created by Administrator on 2022/1/15 0015. */ @Configuration @Slf4j public class TestStartServiceConfig { @Bean @ConditionalOnBean(TestService.class) //--1 //@ConditionalOnMissingBean(TestService.class) //--2 public TestService getTestService(){ log.info("this is a testStartService"); return new TestService(); } } Service类: package com.fql.example.project.autoconfig.service; /** * Created by Administrator on 2022/1/16 0016. */ public class TestService { } Application类: package com.fql.example.project; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.servlet.DispatcherServlet; @SpringBootApplication public class ProjectApplication { public static void main(String[] args) { SpringApplication.run(ProjectApplication.class, args); } }
TestStartServiceConfig中设置为@ConditionalOnBean(TestService.class)输出如下:
2022-01-17 10:36:38.421 INFO 1084 --- [ main] c.f.example.project.ProjectApplication : Starting ProjectApplication using Java 1.8.0_221 on PC-20190113KYFH with PID 1084 (D:\java\fqldemo\project\target\classes started by Administrator in D:\java\fqldemo\project)
2022-01-17 10:36:38.428 INFO 1084 --- [ main] c.f.example.project.ProjectApplication : No active profile set, falling back to default profiles: default
2022-01-17 10:36:39.946 INFO 1084 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2022-01-17 10:36:39.957 INFO 1084 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2022-01-17 10:36:39.957 INFO 1084 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.56]
2022-01-17 10:36:40.070 INFO 1084 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2022-01-17 10:36:40.070 INFO 1084 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1567 ms
2022-01-17 10:36:40.483 INFO 1084 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2022-01-17 10:36:40.497 INFO 1084 --- [ main] c.f.example.project.ProjectApplication : Started ProjectApplication in 2.649 seconds (JVM running for 3.319)
从控制台输出可以发现没有看到TestStartServiceConfig中打印log.info("this is a testStartService");这是因为TestStartService没有实例化,如果我们把TestService改为
@Service
public class TestService {
}
那么输出如下:
2022-01-17 10:39:01.381 INFO 8436 --- [ main] c.f.example.project.ProjectApplication : Starting ProjectApplication using Java 1.8.0_221 on PC-20190113KYFH with PID 8436 (D:\java\fqldemo\project\target\classes started by Administrator in D:\java\fqldemo\project)
2022-01-17 10:39:01.386 INFO 8436 --- [ main] c.f.example.project.ProjectApplication : No active profile set, falling back to default profiles: default
2022-01-17 10:39:02.956 INFO 8436 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2022-01-17 10:39:02.967 INFO 8436 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2022-01-17 10:39:02.967 INFO 8436 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.56]
2022-01-17 10:39:03.085 INFO 8436 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2022-01-17 10:39:03.085 INFO 8436 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1618 ms
2022-01-17 10:39:03.154 INFO 8436 --- [ main] c.f.e.p.a.config.TestStartServiceConfig : this is a testStartService
2022-01-17 10:39:03.465 INFO 8436 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2022-01-17 10:39:03.475 INFO 8436 --- [ main] c.f.example.project.ProjectApplication : Started ProjectApplication in 2.669 seconds (JVM running for 3.348)
TestStartServiceConfig中设置为@ConditionalOnMissingBean(TestService.class)输出如下
2022-01-17 10:39:01.381 INFO 8436 --- [ main] c.f.example.project.ProjectApplication : Starting ProjectApplication using Java 1.8.0_221 on PC-20190113KYFH with PID 8436 (D:\java\fqldemo\project\target\classes started by Administrator in D:\java\fqldemo\project)
2022-01-17 10:39:01.386 INFO 8436 --- [ main] c.f.example.project.ProjectApplication : No active profile set, falling back to default profiles: default
2022-01-17 10:39:02.956 INFO 8436 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2022-01-17 10:39:02.967 INFO 8436 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2022-01-17 10:39:02.967 INFO 8436 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.56]
2022-01-17 10:39:03.085 INFO 8436 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2022-01-17 10:39:03.085 INFO 8436 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1618 ms
2022-01-17 10:39:03.154 INFO 8436 --- [ main] c.f.e.p.a.config.TestStartServiceConfig : this is a testStartService
2022-01-17 10:39:03.465 INFO 8436 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2022-01-17 10:39:03.475 INFO 8436 --- [ main] c.f.example.project.ProjectApplication : Started ProjectApplication in 2.669 seconds (JVM running for 3.348)
当然在这种情况下如果,把改为
@Service
public class TestService {
}
,则 this is a testStartService不会打印,具体输出如下
2022-01-17 10:41:05.079 INFO 8632 --- [ main] c.f.example.project.ProjectApplication : Starting ProjectApplication using Java 1.8.0_221 on PC-20190113KYFH with PID 8632 (D:\java\fqldemo\project\target\classes started by Administrator in D:\java\fqldemo\project)
2022-01-17 10:41:05.083 INFO 8632 --- [ main] c.f.example.project.ProjectApplication : No active profile set, falling back to default profiles: default
2022-01-17 10:41:06.732 INFO 8632 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2022-01-17 10:41:06.744 INFO 8632 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2022-01-17 10:41:06.744 INFO 8632 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.56]
2022-01-17 10:41:06.917 INFO 8632 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2022-01-17 10:41:06.917 INFO 8632 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1747 ms
2022-01-17 10:41:07.290 INFO 8632 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2022-01-17 10:41:07.300 INFO 8632 --- [ main] c.f.example.project.ProjectApplication : Started ProjectApplication in 2.797 seconds (JVM running for 3.472)
补充:
@ConfigurationProperties
使用了@ConfigurationProperties配置之后,可以进一步简化@Value()的使用,最后的结果会变成这个简单
@Configuration
@Data
@Immutable
@ConfigurationProperties(prefix = "spring.kafka")
public class KafkaTopicConfig {
private String errorTopic;
private String successTopic;
}
等价于
@Configuration
@Data
@Immutable
public class KafkaTopicConfig {
@Value("${spring.profiles.errorTopic}")
private String errorTopic;
@Value("${spring.profiles.successTopic}")
private String successTopic;
}
参考:
https://blog.csdn.net/m0_46628950/article/details/125469964
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?