Technology stack:
Springboot 2024.0.0 + MyBatisPlus3 + MySql8 + Hikari connection pool
Preface:
When using the new version of Springboot to build a microservice, I found that the configuration data source failed (Failed to configure a DataSource: ‘url’ attribute is not specified and no emb) is shown in the following figure dependency configuration annotation, etc. All are correct
Notice:
Because the tracking code is too long, it is placed at the end. If you are interested, you can take a look.
Related dependencies are as follows:
<parent> <groupId></groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.4.1</version> <relativePath/> </parent> <dependencies> <!-- MySQL Connector --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.31</version> </dependency> <!-- Mybatis-Plus --> <dependency> <groupId></groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.9</version> </dependency> </dependencies>
The relevant configurations are as follows:
# DataSource Configurationspring: application: name: ai-grading-base # Service name will be registered in Eureka datasource: url: jdbc:mysql://localhost:3306/xxx-xxx?useUnicode=true&characterEncoding=UTF-8&useSSL=false driver-class-name: username: xxx password: yyy hikari: maximum-pool-size: 10 # Set the maximum connection pool size minimum-idle: 5 # Minimum number of idle connections idle-timeout: 30000 # Maximum survival time of idle connection Unit: milliseconds max-lifetime: 600000 # Maximum life cycle of connection Unit: milliseconds connection-timeout: 30000 # Connection timeout unit: milliseconds validation-timeout: 5000 # Check the timeout of the connection Unit: milliseconds leak-detection-threshold: 15000 # Connect leakage detection threshold Unit: milliseconds pool-name: HikariCP # Name of the connection pool auto-commit: true # Whether to enable automatic submission # MyBatis configurationmybatis-plus: mapper-locations: classpath:mapper/* type-aliases-package: configuration: map-underscore-to-camel-case: true #Enable log printing log-impl:
Startup class annotation:
@MapperScan("") @SpringBootApplication public class AiGradingBaseApplication { public static void main(String[] args) { (, args); } }
Failed to configure a DataSource: ‘url’ attribute is not specified and no emb
Development scenario:
Using Mysql 8 configuration failed
Reason for the error:
Prior to Spring Boot 2.4, the loading order of configuration files was performed in the following order:
The loading priority of , is greater than, so if the same configuration item has a definition in both files, the value in , will overwrite the value in ,
Configuration file loading priority
- : Used to configure before loading the application context when the application starts. Usually used to configure service discovery Configuration Center, etc.
- : Used to load configurations after application context loading Commonly used for business-related configurations
Key points:
- There is a higher priority in versions prior to Spring Boot 2.4, so configurations in and repeatedly defined in
- Starting with Spring Boot 2.4, it has been removed and its functionality has been handed over to and Spring Cloud configurations are integrated into
- If you are using a version after Spring Boot 2.4, it should be best to disable it and use it instead for configuration
Main Solution 1: Move the configuration to
Main solution 2: Carefully check whether the MySql (datascoure) configuration file is incorrect, especially Tab indentation, etc. You can refer to the configuration posted above
Main Solution Three: Use Properties to enable boot configuration
The boot configuration of a file can still be enabled by setting the property If the property is set to true Spring Cloud will attempt to load the file and apply the configuration in it to the application's environment.
Key steps:
- make sure
=true
The configuration is activated. It can be set through the system properties environment variables or configuration files. -
Will be automatically loaded and included in the Spring environment
For example, it can be found inor
Configuration in:
=true
Or pass through environment variables or system properties:
-=true
Code level:
In the new version of Spring Cloud()
Methods will checkThe value of the attribute and
Marker
The existence of the class determines whether to enable itbootstrap
Configuration
public static boolean bootstrapEnabled(Environment environment) { return (Boolean) ("", , false) || MARKER_CLASS_EXISTS; }
Main Solution 4: ReadConfiguration file
In the new version of Spring CloudFiles can be loaded directly through Spring's configuration mechanism. Usually there is no need to manually specify the file path. Spring Cloud will use the following
The setting of properties determines whether to load
or
document
TypicalConfiguration file:
spring: cloud: config: uri: http://localhost:8888 bootstrap: enabled: true
This configuration tells the Spring Cloud Config Client toConfig Server
Get the configuration and load it when the application starts
Main Solution 5: UseConfigurableEnvironment
andApplicationContext
Read boot configuration
In Spring Cloud, you can passConfigurableEnvironment
orApplicationContext
To access and readProperties in configuration file
ConfigurableEnvironment environment = (); String configUri = ("", , "http://localhost:8888");
In this way, other properties configured in the file (such as ) can be read and used for the initialization process of the application
Main Solution 6: Manually load the file (if needed)
In some specific application scenarios, files may need to be loaded manually. Spring provides multiple ways to load external configuration files, including using @PropertySource annotation or Environment object. This method is generally used when manually controlling the file loading order or path.
@Configuration @PropertySource("classpath:/") public class BootstrapConfig { @Value("${}") private String configUri; }
Main Solution 7: Bind configuration via @EnableConfigurationProperties
If you want to bind properties in the configuration file to a configuration class, you can use the @EnableConfigurationProperties annotation to enable property binding. This method is also very common in new versions.
@Configuration @EnableConfigurationProperties() public class ConfigBootstrap { // Automatically inject configuration class @Autowired private ConfigProperties configProperties; }
inConfigProperties
Classes can be defined fromConfiguration properties read in the file:
@ConfigurationProperties(prefix = "") public class ConfigProperties { private String uri; // Getter and Setter }
Main Solution 8: Initialize the configuration through ApplicationContextInitializer
Spring Cloud uses ApplicationContextInitializer to initialize Spring application contexts In BootstrapApplicationListener ApplicationContextInitializer is used to handle configuration loading and processing.
If you need to customize the loading logic, you can further control the loading order and method by implementing your own ApplicationContextInitializer:
public class CustomBootstrapApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> { @Override public void initialize(ConfigurableApplicationContext applicationContext) { // Custom initialization logic handles bootstrap configuration } }
And inSpringApplication
Register this initializer at startup:
SpringApplication app = new SpringApplication(); (new CustomBootstrapApplicationContextInitializer()); (args);
Main Solution 9: Use SpringApplication to configure the listener for the program
Spring Cloud uses BootstrapApplicationListener to handle file loading and application configuration. It fires in the ApplicationEnvironmentPreparedEvent event and applies the configuration to the Spring environment.
public class BootstrapApplicationListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered { public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) { ConfigurableEnvironment environment = (); if ((environment)) { // Initialize bootstrap context Load configuration } } }
The remaining solution 1: Add nodes to ensure that the file is scanned normally and loaded successfully (taking SpringBoot 3.4.1 as an example, the official has declared the contents in resources in the dependencies so there is no need to declare them separately)
<build> <finalName>xx-xx-xx</finalName> <plugins> <plugin> <groupId></groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> <resources> <resource> <directory>src/main/java</directory> <includes> <include>/*.yml</include> <include>/*.properties</include> <include>/*.xml</include> </includes> <filtering>false</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>/*.yml</include> <include>/*.properties</include> <include>/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> </build>
The other method 2 (except for special scenarios, the rest are not recommended): add annotation on the enabled class to declare that the data source does not need to be loaded (DataSourceAutoConfiguration)
@MapperScan("") @SpringBootApplication(exclude= {}) public class AiGradingBaseApplication { public static void main(String[] args) { (, args); } }
The other methods three (except for special scenarios, the rest are not recommended): Declaring in the configuration file that data source does not need to be loaded (DataSourceAutoConfiguration) is the same as method two, but the operation mode is inconsistent
spring: autoconfigure: exclude:
Source code tracking:
Preface: Because Springboot's old and new versions are refactored for file loading
official:
Config First Bootstrap To use the legacy bootstrap way of connecting to Config Server, bootstrap must be enabled via a property or the spring-cloud-starter-bootstrap starter. The property is =true. It must be set as a System Property or environment variable. Once bootstrap has been enabled any application with Spring Cloud Config Client on the classpath will connect to Config Server as follows: When a config client starts, it binds to the Config Server (through the bootstrap configuration property) and initializes Spring Environment with remote property sources. The net result of this behavior is that all client applications that want to consume the Config Server need a (or an environment variable) with the server address set in (it defaults to "http://localhost:8888").
translate:
Config First Bootstrap
To connect to Config Server using traditional boot mode, booting must be enabled via the property or spring-cloud-starter-bootstrap launcher. The related property is =true. This property must be set as a system property or environment variable Once boot is enabled Any application containing the Spring Cloud Config Client will be connected to Config Server as follows:
When a configuration client starts it binds to the Config Server (by boot configuration properties) and initializes the Spring environment using a remote property source
The end result of this behavior is that all client applications that want to use Config Server need a file containing the server address configuration (or set via environment variables) The configuration item is (default is "http://localhost:8888")
Brief description:
In earlier versions of Spring Cloudis a key file for configuring Spring Cloud Config Client To enable traditional boot mode connection to Config Server, you must pass
=true
Attribute or throughspring-cloud-starter-bootstrap
Starter to enable boot
Traditional guidance:
- Configuration properties:
=true
Must be set as a system attribute or environment variable - Configuration file: Client application requires one
Files are set in
Attribute (the default value is
http://localhost:8888
) Address to Config Server - Initialization process: At the start of the application
Will be loaded and passed
Properties are connected to Config Server for remote configuration
Related dependencies:
<!-- Old version --> <parent> <groupId></groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.</version> <relativePath/> </parent> <!-- New version --> <parent> <groupId></groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.4.1</version> <relativePath/> </parent>
Old version related source code:
package ; public class BootstrapApplicationListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered { // Define constants: bootstrap configure source name public static final String BOOTSTRAP_PROPERTY_SOURCE_NAME = "bootstrap"; // Define constant: default attribute name public static final String DEFAULT_PROPERTIES = "springCloudDefaultProperties"; // Some codes are omitted... // Constructor public BootstrapApplicationListener() { } // Methods called when listening to the ApplicationEnvironmentPreparedEvent event public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) { // Get the current environment object ConfigurableEnvironment environment = (); // New version - Check whether bootstrap is enabled or traditional processing methods are used // if ((environment) || (environment)) { // Old version - Check if bootstrap is enabled if ((Boolean) ("", , true)) { // If the environment does not contain the property source named "bootstrap" if (!().contains("bootstrap")) { ConfigurableApplicationContext context = null; // The name of the bootstrap that parses the configuration defaults to "bootstrap" String configName = ("${:bootstrap}"); // Get the initializer list of Spring application Iterator var5 = ().getInitializers().iterator(); // Some codes are omitted... } } } }
New version related source code:
package ; import ; import ; public abstract class PropertyUtils { // Define constants: Indicates whether bootstrap configuration is enabled public static final String BOOTSTRAP_ENABLED_PROPERTY = ""; // Define constants: used to mark whether the class exists public static final boolean MARKER_CLASS_EXISTS = ("", (ClassLoader)null); // Method to determine whether bootstrap configuration is enabled public static boolean bootstrapEnabled(Environment environment) { // Get the value of "" configuration default to false return (Boolean) ("", , false) || MARKER_CLASS_EXISTS; } // Some codes are omitted...}
Related core code explanation:
In older versions of Spring CloudBootstrapApplicationListener
Class will monitorApplicationEnvironmentPreparedEvent
Event Check if boot is enabled after the environment configuration is ready () and initialize it
- Code check
Is the attribute?
true
If so, proceedbootstrap
Initialization of context - If not found in the environment
"bootstrap"
Configure source Create the configuration source and perform the corresponding configuration initialization
In the new version of Spring CloudPropertyUtils
The class provides a new method to determine whether it is enabledbootstrap
Configuration
bootstrapEnabled
Method: Check whether it is enabledConfiguration or
Whether the class exists. The existence of this class marks the activation of certain specific functions or versions.
-
Configuration items usually indicate whether the boot function of Spring Cloud Config Client is enabled.
-
MARKER_CLASS_EXISTS
Used to check the classWhether exists Usually in new Spring Cloud versions, the existence of this class indicates whether certain configurations or features are enabled
-
MARKER_CLASS_EXISTS
Constants are used for checkingMarker
Whether the class exists This is part of the new Spring Cloud boot mechanism indicating whether it is enabledbootstrap
Configuration
The core purpose of this method is to determine whether it is enabled based on the configuration and whether the class exists.bootstrap
Configuration source
Key Constants
-
MARKER_CLASS_EXISTS
Constants are used for checkingMarker
Whether the class exists This is part of the new Spring Cloud boot mechanism indicating whether it is enabledbootstrap
Configuration
The main differences between traditional and new versions:
Traditional boot method (old version):
-
: Need to be explicitly configured as
true
Otherwise it will not be enabledbootstrap
Configuration -
: Need to manually configure
and other attributes
- Code flow:
BootstrapApplicationListener
Directly check whether it is enabled during event monitoring.bootstrap
And initialize according to the conditions
New version boot method:
-
bootstrapEnabled
Method: In the new version of Spring CloudMethods provide a more flexible way to check if it is enabled
bootstrap
Not just throughAttributes also passed the check
Marker
The existence of the class is used to judge - Marker class: The new version has been added
Class as a configuration tag class to indicate whether certain functions are enabled
- Improved flexibility: new version of code passes
PropertyUtils
The logic provided by the class to determine whether the boot function is enabled allows for more flexible configuration and judgment
Summarize:
- Old version of Spring Cloud:
is a required configuration file
Used to control whether boot configuration is enabled. After enabled, the Spring Cloud Config Client will automatically connect to the Config Server.
- New version of Spring Cloud: Introduced Pass Check
Marker
The existence of the class is enabled dynamicallybootstrap
The configuration mechanism makes configuration loading more flexible and supports more usage scenarios.or
Marker
The existence of the class Spring Cloud can decide whether to loaddocument
-
PropertyUtils
Class: Provides a simplified method to determine whether to enable itbootstrap
Configure it through judgmentThe value of the attribute and
Marker
The existence of the class determines whether to enable itbootstrap
Configuration makes the new version of the code more concise, flexible and extensible - load
File: Loading in the new version of Spring Cloud
Files depend on
The configuration value and
Marker
The existence of the class When this property is enabled, Spring Cloud will automatically loadFile No need to manually specify the file path. The configuration can be passed
ConfigurableEnvironment
orApplicationContext
Come to access If more complex control is required, developers can customize itApplicationContextInitializer
orApplicationListener
To implement customized configuration loading process
This evolution of boots shows that Spring Cloud maintains compatibility with legacy configurations while continuously optimizing and simplifying configurations