太強了!Spring Boot 五大內置“神兵”工具
環境:SpringBoot3.4.2
1. JSON解析工具
當我們需要在代碼中手動解析 JSON 字符串時,通常會根據當前環境使用的具體 JSON 解析庫來進行操作。如下:
使用jackson時,我們通常會通過如下兩種方式進行解析json字符串:
// 方式1:直接注入
@Resource
private ObjectMapper objectMapper ;
// 方式2:手動創建對象
ObjectMapper mapper = new ObjectMapper() ;
如果使用其它的庫,如gson,那么你就需要創建改庫的解析器,如下:
Gson gson = new GsonBuilder().create()
其實,SpringBoot為我們提供了一個工廠類,通過該工廠類我們不需要知道底層使用的具體什么庫,該工廠類會自動判斷選擇。
String json = """
{
"name": "pack",
"sex": "男",
"age": 22,
"idNo": "640522199303092164"
}
""" ;
JsonParser jsonParser = JsonParserFactory.getJsonParser() ;
Map<String, Object> ret = jsonParser.parseMap(json) ;
System.err.println(ret) ;
輸出結果
{name=pack, sex=男, age=22, idNo=640522199303092164}
該工廠內部實現:
圖片
2. 執行數據庫腳本
當我們在項目中,需要在服務啟動時自動的執行sql腳本,我們可以通過定義如下的bean對象。
@Configuration
public class DatabaseScriptExecution {
@Bean
DataSourceScriptDatabaseInitializer databaseInitializer(DataSource dataSource) {
DatabaseInitializationSettings settings = new DatabaseInitializationSettings() ;
settings.setEncoding(StandardCharsets.UTF_8) ;
settings.setSchemaLocations(List.of("classpath:db/db.sql",
"optional:classpath:db/data.sql")) ;
DataSourceScriptDatabaseInitializer init = new DataSourceScriptDatabaseInitializer(dataSource, settings) ;
return init ;
}
}
在具體的資源前,我們可以通過 optional: 前綴來設置該資源是可選的,也就是如果該資源不存在也不會引發錯誤。
以上通過代碼自定義配置,其實在Spring Boot中,已經為我們提供了功能,可以通過配置自動的執行腳本,如下配置:
spring:
sql:
init:
mode: always
username: root
password: xxxooo
encoding: UTF-8
schema-locations:
- optional:classpath:db/schema.sql
data-locations:
- optional:classpath:db/data.sql
3. 自定義數據源配置
當我們需要自定義數據源DataSource bean的配置時,我們可以通過DataSourceBuilder類快捷創建:
@Configuration
public class DataSourceConfig {
@Bean
DataSource createDataSource() {
return DataSourceBuilder.create()
.type(HikariDataSource.class)
.driverClassName("com.mysql.cj.jdbc.Driver")
.url("jdbc:mysql://localhost:3306/ds2")
.username("root")
.password("xxxooo")
.build();
}
}
該構建器支持以下連接池 DataSource 實現類型。當未顯式設置類型時,將選擇第一個可用的連接池實現:
- Hikari(com.zaxxer.hikari.HikariDataSource)
- Tomcat JDBC Pool(org.apache.tomcat.jdbc.pool.DataSource)
- Apache DBCP2(org.apache.commons.dbcp2.BasicDataSource)
- Oracle UCP(oracle.ucp.jdbc.PoolDataSourceImpl)
- C3P0(com.mchange.v2.c3p0.ComboPooledDataSource)
4. properties&yaml解析器
當需要讀取properties或者yaml配置文件時,Spring Boot為我們分別提供了讀取properties和yaml兩種格式文件的工具類,如下示例:
properties文件
PropertiesPropertySourceLoader loader = new PropertiesPropertySourceLoader() ;
ClassPathResource resource = new ClassPathResource("user.properties") ;
List<PropertySource<?>> sources = loader.load("user", resource) ;
sources.forEach(source -> {
System.err.println(source.getName() + "@" + source.getSource()) ;
}) ;
輸出結果
user@{pack.name=pack, pack.versinotallow=1.0.0, pack.title=xxxooo}
yaml文件
YamlPropertySourceLoader loader = new YamlPropertySourceLoader() ;
// ...其它代碼都與上面一致
如果你希望定義成一個bean,那么你還可以通過如下的方式:
@Bean
YamlPropertiesFactoryBean yamlFactoryBean() {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean() ;
factory.setResources(new ClassPathResource("user.yaml")) ;
return factory ;
}
5. 數據綁定
有時,我們可能需要在程序中通過編碼的方式將配置信息綁定到一個對象上,那么我們可以通過Binder完成此功能:
// 實際Environment對象,我們只需要注入即可
StandardEnvironment env = new StandardEnvironment() ;
env.getPropertySources().addFirst(
new SimpleCommandLinePropertySource("--pack.title=xxxooo", "---pack.versinotallow=1.0.0")) ;
Binder binder = Binder.get(env) ;
BindResult<App> result = binder.bind("pack", App.class) ;
System.err.println(result.get()) ;
public static record App(String title, String version) {}
輸出結果
App[title=xxxooo, versinotallow=1.0.0]
綁定請求參數
如果你需要將HttpServletRequest中的參數綁定到對象,那么你可以如下操作:
DataBinder bbb = new DataBinder(new App()) ;
HttpServletRequest request = ... ;
PropertyValues values = new ServletRequestParameterPropertyValues(request) ;
bbb.bind(values) ;
Object target = bbb.getTarget() ;
有效性校驗
如果你還需要對數據的有效性進行校驗,那么你可以如下操作:
DataBinder bbb = new DataBinder(new App()) ;
// 設置校驗器,在Spring Boot環境下,你可以直接注入該對象
LocalValidatorFactoryBean validator = ... ;
bbb.setValidator(validator);
// 校驗數據
bbb.validate();
bbb.getBindingResult().getFieldErrors().forEach(error -> {
System.err.println(error.getField() + " @ " + error.getDefaultMessage()) ;
});
// App實體對象
public class App {
@NotEmpty(message = "標題不能空")
private String title ;
private String version ;
}