springboot配置文件yml读取不到。

本文详细记录了SpringBoot应用中日志框架Logback的配置过程,包括控制台和滚动文件日志的设置。同时,揭示了在数据源初始化阶段遇到的问题,如未指定数据库URL和无法确定合适的驱动类,提供了相应的解决策略。

数据源配置在这里插入图片描述
appenders present in context [logback] for logger [org.springframework.core.env.PropertySourcesPropertyResolver].
11:54:10,274 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - Will scan for changes in [file:/D:/p2-spot/target/classes/logback.xml]
11:54:10,274 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - Setting ReconfigureOnChangeTask scanning period to 1 seconds
11:54:10,275 |-INFO in ch.qos.logback.classic.joran.action.ContextNameAction - Setting logger context name as [logback]
11:54:10,275 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
11:54:10,275 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT]
11:54:10,275 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
11:54:10,276 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.rolling.RollingFileAppender]
11:54:10,276 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [FILE]
11:54:10,277 |-INFO in c.q.l.core.rolling.TimeBasedRollingPolicy@802771878 - No compression will be used
11:54:10,277 |-INFO in c.q.l.core.rolling.TimeBasedRollingPolicy@802771878 - Will use the pattern logback_test/log/.%d{yyyy-MM-dd}.log for the active file
11:54:10,278 |-INFO in c.q.l.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy - The date pattern is ‘yyyy-MM-dd’ from file name pattern ‘logback_test/log/.%d{yyyy-MM-dd}.log’.
11:54:10,278 |-INFO in c.q.l.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy - Roll-over at midnight.
11:54:10,279 |-INFO in c.q.l.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy - Setting initial period to Thu Jan 09 11:54:10 CST 2020
11:54:10,279 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
11:54:10,280 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[FILE] - Active log file name: logback_test/log/.2020-01-09.log
11:54:10,280 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[FILE] - File property is set to [null]
11:54:10,281 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [com.apache.ibatis] to TRACE
11:54:10,281 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [java.sql.Connection] to DEBUG
11:54:10,281 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [java.sal.Statement] to DEBUG
11:54:10,281 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [java.sql.PreparedStatement] to DEBUG
11:54:10,281 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to INFO
11:54:10,281 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[ROOT]
11:54:10,281 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [FILE] to Logger[ROOT]
11:54:10,281 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.
11:54:10,281 |-INFO in org.springframework.boot.logging.logback.SpringBootJoranConfigurator@a4add54 - Registering current configuration as safe fallback point

. ____ _ __ _ _
/\ / __ _ () __ __ _ \ \ \
( ( )_
_ | '_ | '| | ’ / ` | \ \ \
\/ )| |)| | | | | || (| | ) ) ) )
’ |
| .__|| ||| |__, | / / / /
=|_|======|/=////
:: Spring Boot :: (v2.0.3.RELEASE)

2020-01-09 11:54:10.389 [main] INFO cn.paohe.Application - Starting Application on DESKTOP-KLFM7T1 with PID 18328 (D:\p2-spot\target\classes started by user in D:\p2-spot)
2020-01-09 11:54:10.393 [main] INFO cn.paohe.Application - No active profile set, falling back to default profiles: default
2020-01-09 11:54:10.453 [main] INFO o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext - Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@2e6a5539: startup date [Thu Jan 09 11:54:10 CST 2020]; root of context hierarchy
2020-01-09 11:54:11.042 [main] WARN org.mybatis.spring.mapper.ClassPathMapperScanner - No MyBatis mapper was found in ‘[cn.paohe.spot.dao]’ package. Please check your configuration.
2020-01-09 11:54:11.128 [main] WARN org.mybatis.spring.mapper.ClassPathMapperScanner - No MyBatis mapper was found in ‘[cn.paohe]’ package. Please check your configuration.
2020-01-09 11:54:11.162 [main] INFO o.s.d.r.config.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode!
2020-01-09 11:54:11.512 [main] INFO o.s.c.s.PostProcessorRegistrationDelegateBeanPostProcessorChecker−Bean′org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration′oftype[org.springframework.transaction.annotation.ProxyTransactionManagementConfigurationBeanPostProcessorChecker - Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfigurationBeanPostProcessorCheckerBeanorg.springframework.transaction.annotation.ProxyTransactionManagementConfigurationoftype[org.springframework.transaction.annotation.ProxyTransactionManagementConfigurationEnhancerBySpringCGLIBEnhancerBySpringCGLIBEnhancerBySpringCGLIB22ef58f8]isnoteligibleforgettingprocessedbyallBeanPostProcessors(forexample:noteligibleforauto−proxying)2020−01−0911:54:11.747[main]INFOorg.xnio−XNIOversion3.3.8.Final2020−01−0911:54:11.761[main]INFOorg.xnio.nio−XNIONIOImplementationVersion3.3.8.Final2020−01−0911:54:11.790[main]WARNio.undertow.websockets.jsr−UT026009:XNIOworkerwasnotsetonWebSocketDeploymentInfo,thedefaultworkerwillbeused2020−01−0911:54:11.790[main]WARNio.undertow.websockets.jsr−UT026010:BufferpoolwasnotsetonWebSocketDeploymentInfo,thedefaultpoolwillbeused2020−01−0911:54:11.811[main]INFOio.undertow.servlet−InitializingSpringembeddedWebApplicationContext2020−01−0911:54:11.812[main]INFOorg.springframework.web.context.ContextLoader−RootWebApplicationContext:initializationcompletedin1359ms2020−01−0911:54:11.910[main]INFOo.s.boot.web.servlet.ServletRegistrationBean−ServletdispatcherServletmappedto[/]2020−01−0911:54:11.914[main]INFOo.s.boot.web.servlet.FilterRegistrationBean−Mappingfilter:′characterEncodingFilter′to:[/∗]2020−01−0911:54:11.914[main]INFOo.s.boot.web.servlet.FilterRegistrationBean−Mappingfilter:′hiddenHttpMethodFilter′to:[/∗]2020−01−0911:54:11.915[main]INFOo.s.boot.web.servlet.FilterRegistrationBean−Mappingfilter:′httpPutFormContentFilter′to:[/∗]2020−01−0911:54:11.915[main]INFOo.s.boot.web.servlet.FilterRegistrationBean−Mappingfilter:′requestContextFilter′to:[/∗]2020−01−0911:54:12.290[main]INFOo.s.web.servlet.handler.SimpleUrlHandlerMapping−MappedURLpath[/∗∗/favicon.ico]ontohandleroftype[classorg.springframework.web.servlet.resource.ResourceHttpRequestHandler]2020−01−0911:54:12.530[main]INFOo.s.w.s.m.m.a.RequestMappingHandlerAdapter−Lookingfor@ControllerAdvice:org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@2e6a5539:startupdate[ThuJan0911:54:10CST2020];rootofcontexthierarchy2020−01−0911:54:12.647[main]INFOo.s.w.s.m.m.a.RequestMappingHandlerMapping−Mapped"[/error]"ontopublicorg.springframework.http.ResponseEntity<java.util.Map<java.lang.String,java.lang.Object>>org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)2020−01−0911:54:12.648[main]INFOo.s.w.s.m.m.a.RequestMappingHandlerMapping−Mapped"[/error],produces=[text/html]"ontopublicorg.springframework.web.servlet.ModelAndVieworg.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)2020−01−0911:54:12.675[main]INFOo.s.web.servlet.handler.SimpleUrlHandlerMapping−MappedURLpath[/webjars/∗∗]ontohandleroftype[classorg.springframework.web.servlet.resource.ResourceHttpRequestHandler]2020−01−0911:54:12.675[main]INFOo.s.web.servlet.handler.SimpleUrlHandlerMapping−MappedURLpath[/∗∗]ontohandleroftype[classorg.springframework.web.servlet.resource.ResourceHttpRequestHandler]2020−01−0911:54:12.747[main]INFOc.a.d.s.b.a.DruidDataSourceAutoConfigure−InitDruidDataSource2020−01−0911:54:12.785[main]WARNo.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext−Exceptionencounteredduringcontextinitialization−cancellingrefreshattempt:org.springframework.beans.factory.BeanCreationException:Errorcreatingbeanwithname′dataSource′definedinclasspathresource[com/alibaba/druid/spring/boot/autoconfigure/DruidDataSourceAutoConfigure.class]:Invocationofinitmethodfailed;nestedexceptionisorg.springframework.boot.autoconfigure.jdbc.DataSourceProperties22ef58f8] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2020-01-09 11:54:11.747 [main] INFO org.xnio - XNIO version 3.3.8.Final 2020-01-09 11:54:11.761 [main] INFO org.xnio.nio - XNIO NIO Implementation Version 3.3.8.Final 2020-01-09 11:54:11.790 [main] WARN io.undertow.websockets.jsr - UT026009: XNIO worker was not set on WebSocketDeploymentInfo, the default worker will be used 2020-01-09 11:54:11.790 [main] WARN io.undertow.websockets.jsr - UT026010: Buffer pool was not set on WebSocketDeploymentInfo, the default pool will be used 2020-01-09 11:54:11.811 [main] INFO io.undertow.servlet - Initializing Spring embedded WebApplicationContext 2020-01-09 11:54:11.812 [main] INFO org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization completed in 1359 ms 2020-01-09 11:54:11.910 [main] INFO o.s.boot.web.servlet.ServletRegistrationBean - Servlet dispatcherServlet mapped to [/] 2020-01-09 11:54:11.914 [main] INFO o.s.boot.web.servlet.FilterRegistrationBean - Mapping filter: 'characterEncodingFilter' to: [/*] 2020-01-09 11:54:11.914 [main] INFO o.s.boot.web.servlet.FilterRegistrationBean - Mapping filter: 'hiddenHttpMethodFilter' to: [/*] 2020-01-09 11:54:11.915 [main] INFO o.s.boot.web.servlet.FilterRegistrationBean - Mapping filter: 'httpPutFormContentFilter' to: [/*] 2020-01-09 11:54:11.915 [main] INFO o.s.boot.web.servlet.FilterRegistrationBean - Mapping filter: 'requestContextFilter' to: [/*] 2020-01-09 11:54:12.290 [main] INFO o.s.web.servlet.handler.SimpleUrlHandlerMapping - Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2020-01-09 11:54:12.530 [main] INFO o.s.w.s.m.m.a.RequestMappingHandlerAdapter - Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@2e6a5539: startup date [Thu Jan 09 11:54:10 CST 2020]; root of context hierarchy 2020-01-09 11:54:12.647 [main] INFO o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest) 2020-01-09 11:54:12.648 [main] INFO o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) 2020-01-09 11:54:12.675 [main] INFO o.s.web.servlet.handler.SimpleUrlHandlerMapping - Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2020-01-09 11:54:12.675 [main] INFO o.s.web.servlet.handler.SimpleUrlHandlerMapping - Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2020-01-09 11:54:12.747 [main] INFO c.a.d.s.b.a.DruidDataSourceAutoConfigure - Init DruidDataSource 2020-01-09 11:54:12.785 [main] WARN o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [com/alibaba/druid/spring/boot/autoconfigure/DruidDataSourceAutoConfigure.class]: Invocation of init method failed; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties22ef58f8]isnoteligibleforgettingprocessedbyallBeanPostProcessors(forexample:noteligibleforautoproxying)2020010911:54:11.747[main]INFOorg.xnioXNIOversion3.3.8.Final2020010911:54:11.761[main]INFOorg.xnio.nioXNIONIOImplementationVersion3.3.8.Final2020010911:54:11.790[main]WARNio.undertow.websockets.jsrUT026009:XNIOworkerwasnotsetonWebSocketDeploymentInfo,thedefaultworkerwillbeused2020010911:54:11.790[main]WARNio.undertow.websockets.jsrUT026010:BufferpoolwasnotsetonWebSocketDeploymentInfo,thedefaultpoolwillbeused2020010911:54:11.811[main]INFOio.undertow.servletInitializingSpringembeddedWebApplicationContext2020010911:54:11.812[main]INFOorg.springframework.web.context.ContextLoaderRootWebApplicationContext:initializationcompletedin1359ms2020010911:54:11.910[main]INFOo.s.boot.web.servlet.ServletRegistrationBeanServletdispatcherServletmappedto[/]2020010911:54:11.914[main]INFOo.s.boot.web.servlet.FilterRegistrationBeanMappingfilter:characterEncodingFilterto:[/]2020010911:54:11.914[main]INFOo.s.boot.web.servlet.FilterRegistrationBeanMappingfilter:hiddenHttpMethodFilterto:[/]2020010911:54:11.915[main]INFOo.s.boot.web.servlet.FilterRegistrationBeanMappingfilter:httpPutFormContentFilterto:[/]2020010911:54:11.915[main]INFOo.s.boot.web.servlet.FilterRegistrationBeanMappingfilter:requestContextFilterto:[/]2020010911:54:12.290[main]INFOo.s.web.servlet.handler.SimpleUrlHandlerMappingMappedURLpath[//favicon.ico]ontohandleroftype[classorg.springframework.web.servlet.resource.ResourceHttpRequestHandler]2020010911:54:12.530[main]INFOo.s.w.s.m.m.a.RequestMappingHandlerAdapterLookingfor@ControllerAdvice:org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@2e6a5539:startupdate[ThuJan0911:54:10CST2020];rootofcontexthierarchy2020010911:54:12.647[main]INFOo.s.w.s.m.m.a.RequestMappingHandlerMappingMapped"[/error]"ontopublicorg.springframework.http.ResponseEntity<java.util.Map<java.lang.String,java.lang.Object>>org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)2020010911:54:12.648[main]INFOo.s.w.s.m.m.a.RequestMappingHandlerMappingMapped"[/error],produces=[text/html]"ontopublicorg.springframework.web.servlet.ModelAndVieworg.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)2020010911:54:12.675[main]INFOo.s.web.servlet.handler.SimpleUrlHandlerMappingMappedURLpath[/webjars/]ontohandleroftype[classorg.springframework.web.servlet.resource.ResourceHttpRequestHandler]2020010911:54:12.675[main]INFOo.s.web.servlet.handler.SimpleUrlHandlerMappingMappedURLpath[/]ontohandleroftype[classorg.springframework.web.servlet.resource.ResourceHttpRequestHandler]2020010911:54:12.747[main]INFOc.a.d.s.b.a.DruidDataSourceAutoConfigureInitDruidDataSource2020010911:54:12.785[main]WARNo.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContextExceptionencounteredduringcontextinitializationcancellingrefreshattempt:org.springframework.beans.factory.BeanCreationException:ErrorcreatingbeanwithnamedataSourcedefinedinclasspathresource[com/alibaba/druid/spring/boot/autoconfigure/DruidDataSourceAutoConfigure.class]:Invocationofinitmethodfailed;nestedexceptionisorg.springframework.boot.autoconfigure.jdbc.DataSourcePropertiesDataSourceBeanCreationException: Failed to determine a suitable driver class
2020-01-09 11:54:12.785 [main] INFO o.s.jmx.export.annotation.AnnotationMBeanExporter - Unregistering JMX-exposed beans on shutdown
2020-01-09 11:54:12.805 [main] INFO o.s.b.a.l.ConditionEvaluationReportLoggingListener -

Error starting ApplicationContext. To display the conditions report re-run your application with ‘debug’ enabled.
2020-01-09 11:54:12.807 [main] ERROR o.s.b.diagnostics.LoggingFailureAnalysisReporter -


APPLICATION FAILED TO START


Description:

Failed to configure a DataSource: ‘url’ attribute is not specified and no embedded datasource could be configured.

Reason: Failed to determine a suitable driver class

Action:

Consider the following:
If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).

Disconnected from the target VM, address: ‘127.0.0.1:61248’, transport: ‘socket’

Process finished with exit code 1

解决方法
在这里插入图片描述
改为
在这里插入图片描述
启动成功!

<think>我们正在处理的问题是在Spring Boot的YAML配置文件中使用`@...@`语法读取pom.xml变量时出现错误。具体报错信息是`org.yaml.snakeyaml.scanner.ScannerException: while scanning for the next token found character '@' that cannot start any token`。 根本原因:Spring Boot的配置文件默认使用YAML格式解析,而YAML解析器(SnakeYAML)会将`@`视为非法字符(因为它不是YAML标记的合法起始字符)。当我们尝试在YAML中使用`@...@`占位符时,解析器会在扫描到第一个`@`字符时报错。 然而,在Spring Boot中,我们通常使用`@...@`语法来引用Maven属性(通过资源过滤实现)。这个语法在`application.properties`文件中是有效的,但在`application.yml`中直接使用会导致YAML解析错误。 解决方案: 1. **使用`application.properties`替代**:将配置文件改为`application.properties`格式,因为`.properties`文件不会将`@`视为特殊字符。 2. **在YAML中避免直接使用`@...@`语法**:通过转义或改变写法来实现。 3. **使用Spring Boot的多文档块特性(YAML)**:在Spring Boot 2.4及以上版本,我们可以使用多文档块来定义需要资源过滤的部分,然后通过`spring.config.activate.on-profile`将其隔离,避免被YAML解析器直接解析。 具体步骤: **方法一:改用properties文件** 将`application.yml`重命名为`application.properties`,然后在其中使用`@...@`语法: ```properties app.version=@project.version@ ``` **方法二:在YAML中使用单引号转义(不推荐)** 注意:这种方法并不总是有效,因为YAML解析器仍然可能将`@`视为非法字符。但可以尝试: ```yaml app: version: '@project.version@' # 使用单引号包裹 ``` 但是,如果这样写,在资源过滤时,单引号会被一起替换,导致实际值带有单引号(如`'1.0.0'`),可能不是我们想要的。 **方法三(推荐):使用YAML多文档块和资源过滤分离** 步骤: 1. 在`pom.xml`中启用资源过滤,并指定需要过滤的文件(包括YAML文件): ```xml <build> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> <includes> <include>**/application.yml</include> </includes> </resource> </resources> </build> ``` 2. 在`application.yml`中,将包含`@...@`的部分放在一个独立的多文档块中,并标记为`spring.config.activate.on-profile`为`!maven`(一个不存在的profile,这样这部分配置不会在运行时被激活,但会被资源过滤处理): ```yaml # 其他配置 spring: application: name: demo --- # 这个文档块用于资源过滤,不会被加载到实际配置中 spring: config: activate: on-profile: !maven # 在这里使用@...@语法 app: version: @project.version@ ``` 3. 然后,我们需要在另一个地方(比如一个正常的文档块)使用`${app.version}`来引用这个值,但是注意:由于这个文档块被标记为`!maven`,它不会在运行时被加载,所以这种方法实际上不可行。 因此,我们需要改变思路:将需要过滤的属性单独放在一个文件中,然后在主配置文件中通过`spring.profiles.include`来引入,但这样同样会遇到解析问题。 鉴于以上,更实用的方法是: **方法四(推荐):使用单独的properties文件进行过滤** 1. 创建一个单独的属性文件(如`maven.properties`),在其中使用`@...@`语法: ```properties app.version=@project.version@ ``` 2. 在`pom.xml`中只对这个文件进行过滤: ```xml <build> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> <includes> <include>**/maven.properties</include> </includes> </resource> </resources> </build> ``` 3. 在`application.yml`中,通过`@PropertySource`引入这个文件(但注意,Spring Boot默认不支持在YAML中使用`@PropertySource`,所以需要转换思路): 我们可以使用`spring.config.import`来引入这个properties文件(Spring Boot 2.4+支持): ```yaml spring: config: import: optional:classpath:maven.properties ``` 4. 然后在代码中就可以使用`@Value("${app.version}")`来获取值。 但是,这种方法有一个缺点:`maven.properties`中的属性不能直接作为YAML中的变量使用(比如在YAML中引用`${app.version}`),因为它们是两个不同的属性源。 因此,更简洁的方法还是使用`application.properties`。 结论:**在Spring Boot中,如果需要在配置文件中使用Maven资源过滤(即`@...@`语法),建议使用`application.properties`格式而不是`application.yml`。** 如果坚持使用YAML,可以考虑以下替代方案: - 在构建时生成一个包含版本信息的Java类(使用`build-helper-maven-plugin`)。 - 使用Spring Boot的`InfoContributor`来自定义/info端点的版本信息(通过Maven插件生成一个属性文件,然后由`InfoContributor`读取)。 但是,对于一般的配置属性,使用`application.properties`是最简单的。 如果问题仍然存在,请检查: - 确保`pom.xml`中开启了资源过滤(`<filtering>true</filtering>`)。 - 确保资源目录正确(`src/main/resources`)。 引用: [^1]: YAML规范中,`@`是保留字符,不能作为普通字符出现在标记外。 [^2]: Spring Boot文档中说明,资源过滤在YAML文件中使用需要特殊处理。</think>### 问题原因分析 在 Spring Boot 的 YAML 配置文件中直接使用 `@...@` 语法读取 Maven 变量时,会出现 `ScannerException` 错误,根本原因是: 1. **YAML 语法冲突** `@` 字符在 YAML 规范中是**保留字符**(用于表示锚点和别名),不能直接作为普通字符使用。当 SnakeYAML 解析器遇到未转义的 `@` 时,会触发词法分析错误[^1]。 2. **资源过滤时机问题** Maven 的资源过滤(`<filtering>true</filtering>`)发生在 YAML 文件被加载之前,但 `@...@` 语法需要**先被 Maven 处理**,而 YAML 解析器会抢先拦截该字符[^2]。 3. **Spring Boot 特殊处理缺失** 与 `.properties` 文件不同,Spring Boot 对 YAML 中的 `@...@` 语法**没有内置转义机制**,导致解析失败[^3]。 --- ### 解决方案 #### 方法 1:启用 YAML 资源过滤(推荐) 在 `pom.xml` 中显式配置资源过滤: ```xml <build> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> <!-- 关键配置 --> <includes> <include>**/application.yml</include> </includes> </resource> </resources> </build> ``` 然后在 YAML 文件中使用**转义语法**: ```yaml app: version: '@project.version@' # 单引号包裹 buildTime: '@timestamp@' ``` #### 方法 2:使用属性文件桥接 1. 在 `src/main/resources` 创建 `maven.properties`: ```properties app.version=@project.version@ build.time=@timestamp@ ``` 2. 在 YAML 中通过 Spring Boot 导入: ```yaml spring: config: import: classpath:maven.properties # Spring Boot 2.4+ app: version: ${app.version} # 安全引用 build: ${build.time} ``` #### 方法 3:自定义 Maven 占位符 修改 Maven 资源过滤的占位符(避免 `@` 冲突): ```xml <properties> <resource.delimiter>${}</resource.delimiter> <!-- 改为 ${...} 语法 --> </properties> ``` 在 YAML 中直接使用: ```yaml app: version: ${project.version} # 不再冲突 ``` --- ### 验证步骤 1. **检查过滤结果** 构建后查看 `target/classes/application.yml`,确认变量已被替换: ```bash mvn clean package cat target/classes/application.yml ``` 2. **运行时验证** 在 Spring Boot 中通过 `@Value` 注入: ```java @Value("${app.version}") private String version; ``` --- ### 预防措施 ```yaml # 正确示例 (application.yml) security: # 关键:特殊值用引号包裹 token: '@security.token@' # ✅ 单引号包裹 # 普通值无需引号 expire: 3600 ``` > **最佳实践**:对于复杂配置,推荐使用 **Spring Cloud Config** 或 **Kubernetes ConfigMap** 实现动态配置管理[^4]。 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值