鎼炲畾SpringBoot澶氭暟鎹簮锛氬姩鎬佹暟鎹簮
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了鎼炲畾SpringBoot澶氭暟鎹簮锛氬姩鎬佹暟鎹簮相关的知识,希望对你有一定的参考价值。
鏍囩锛?a href='http://www.mamicode.com/so/1/thold' title='thold'>thold out 瀹氫箟 odi select autowired extend
鐩綍
涓€鍙ヨ瘽姒傛嫭锛氫娇鐢ㄥ姩鎬佹暟鎹簮瀵瑰涓暟鎹簱杩涜鎿嶄綔锛岀伒娲伙紝绠€娲併€?/p>
1. 寮曡█
瀵逛簬澶氫釜鏁版嵁搴撶殑澶勭悊锛屼笂涓€绡囨枃绔犮€?a href="https://mp.weixin.qq.com/s/0J-FLYScYtEMnj0vZToX7g">鎼炲畾SpringBoot澶氭暟鎹簮(1)锛氬濂楁簮绛栫暐銆嬪凡鏈夋彁鍙婏紝鏈夊濂楁暟鎹簮銆佸姩鎬佹暟鎹簮銆佸弬鏁板寲鍙樻洿鏁版嵁婧愮瓑鏂瑰紡锛屾湰鏂囨槸绗簩绡囷細鈥滃姩鎬佹暟鎹簮鈥濄€傚姩鎬佹暟鎹簮鍙互瑙e喅澶氬鏁版嵁婧愮殑澶勭悊涓嶅鐏垫椿銆佸崰鐢ㄨ祫婧愬绛夐棶棰樸€傜敤鎴峰彲浠ユ牴鎹疄闄呯殑涓氬姟闇€瑕侊紝缁熶竴鎿嶄綔閫昏緫锛屽彧瑕佸湪闇€瑕佸垏鎹㈡暟鎹簮鐨勮繘琛屽鐞嗗嵆鍙€備綍涓哄姩鎬侊紝鍏跺疄鏄壒鍒囨崲鏁版嵁婧愮殑鏃舵満鍙互鍔ㄦ€侀€夋嫨锛屽湪闇€瑕佺殑鍦版柟杩涜鍒囨崲鍗冲彲銆?/p>
鏈枃寤剁画涓婁竴绡囨枃绔犵殑绀轰緥锛屼互涓讳粠鍦烘櫙涓虹ず渚嬶紝缁撳悎浠g爜锛屽鍔ㄦ€佹暟鎹簮鐨勫疄鐜拌繘琛岃瑙o紝鍐呭鍖呮嫭鎼缓鍔ㄦ€佹暟鎹簮鍘熺悊銆佸姩鎬佹暟鎹簮閰嶇疆銆佸姩鎬佹暟鎹簮浣跨敤锛孉OP 娉ㄨВ鏂瑰紡鍒囨崲鏁版嵁婧愮瓑銆?/p>
鏈枃鎵€娑夊強鍒扮殑绀轰緥浠g爜:https://github.com/mianshenglee/my-example/tree/master/multi-datasource
锛岃鑰呭彲缁撳悎涓€璧风湅銆?/p>
2. 鍔ㄦ€佹暟鎹簮娴佺▼璇存槑
Spring Boot 鐨勫姩鎬佹暟鎹簮锛屾湰璐ㄤ笂鏄妸澶氫釜鏁版嵁婧愬瓨鍌ㄥ湪涓€涓?Map 涓紝褰撻渶瑕佷娇鐢ㄦ煇涓暟鎹簮鏃讹紝浠?Map 涓幏鍙栨鏁版嵁婧愯繘琛屽鐞嗐€傝€屽湪 Spring 涓紝宸叉彁渚涗簡鎶借薄绫?AbstractRoutingDataSource
鏉ュ疄鐜版鍔熻兘銆傚洜姝わ紝鎴戜滑鍦ㄥ疄鐜板姩鎬佹暟鎹簮鐨勶紝鍙渶瑕佺户鎵垮畠锛屽疄鐜拌嚜宸辩殑鑾峰彇鏁版嵁婧愰€昏緫鍗冲彲銆傚姩鎬佹暟鎹簮娴佺▼濡備笅鎵€绀猴細
鐢ㄦ埛璁块棶搴旂敤锛屽湪闇€瑕佽闂笉鍚岀殑鏁版嵁婧愭椂锛屾牴鎹嚜宸辩殑鏁版嵁婧愯矾鐢遍€昏緫锛岃闂笉鍚岀殑鏁版嵁婧愶紝瀹炵幇瀵瑰簲鏁版嵁婧愮殑鎿嶄綔銆傛湰绀轰緥涓殑涓ゆ暟鎹簱鐨勫垎鍒湁涓€涓〃 test_user
锛岃〃缁撴瀯涓€鑷达紝涓轰究浜庤鏄庯紝涓や釜琛ㄤ腑鐨勬暟鎹槸涓嶄竴鏍风殑銆備袱涓〃缁撴瀯鍙湪绀轰緥浠g爜涓殑 sql
鐩綍涓幏鍙栥€?/p>
3. 瀹炵幇鍔ㄦ€佹暟鎹簮
3.1 璇存槑鍙婃暟鎹簮閰嶇疆
鈹溾攢annotation ---- // 鑷畾涔夋敞瑙?鈹溾攢aop ----------- // 鍒囬潰
鈹溾攢config -------- // 鏁版嵁婧愰厤缃?鈹溾攢constants ----- // 甯哥敤娉ㄨВ
鈹溾攢context ------- // 鑷畾涔変笂涓嬫枃
鈹溾攢controller ---- // 璁块棶鎺ュ彛
鈹溾攢entity -------- // 瀹炰綋
鈹溾攢mapper -------- // 鏁版嵁搴揹ao鎿嶄綔
鈹溾攢service ------- // 鏈嶅姟绫?鈹斺攢vo ------------ // 瑙嗗浘杩斿洖鏁版嵁
# master
spring.datasource.master.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.master.jdbc-url=jdbc:mysql://localhost:3306/mytest?useSSL=false&serverTimezone=GMT%2B8&characterEncoding=UTF-8
spring.datasource.master.username=root
spring.datasource.master.password=111111
# slave
spring.datasource.slave.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.slave.jdbc-url=jdbc:mysql://localhost:3306/my_test1?useSSL=false&serverTimezone=GMT%2B8&characterEncoding=UTF-8
spring.datasource.slave.username=root
spring.datasource.slave.password=111111
@Configuration
@PropertySource("classpath:config/jdbc.properties")
@MapperScan(basePackages = "me.mason.demo.dynamicdatasource.mapper")
public class DynamicDataSourceConfig {
@Bean(DataSourceConstants.DS_KEY_MASTER)
@ConfigurationProperties(prefix = "spring.datasource.master")
public DataSource masterDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(DataSourceConstants.DS_KEY_SLAVE)
@ConfigurationProperties(prefix = "spring.datasource.slave")
public DataSource slaveDataSource() {
return DataSourceBuilder.create().build();
}
}
娉ㄦ剰锛?/p>
- 姝ゅ浣跨敤
PropertySource
鎸囧畾閰嶇疆鏂囦欢锛?code>ConfigurationProperties 鎸囧畾鏁版嵁婧愰厤缃墠缂€
- 浣跨敤
MapperScan
鎸囧畾鍖咃紝鑷姩娉ㄥ叆鐩稿簲鐨?mapper 绫汇€?/li>
- 鎶婃暟鎹簮甯搁噺鍐欏湪
DataSourceConstants
绫讳腑
- 浠庢閰嶇疆鍙互鐪嬪埌锛屽凡缁忔妸 SqlSessionFactory 杩欎釜閰嶇疆浠庝唬鐮佷腑鎿﹂櫎锛岀洿鎺ヤ娇鐢?Spring Boot 鑷姩閰嶇疆鐨?SqlSessionFactory 鍗冲彲锛屾棤闇€鎴戜滑鑷繁閰嶇疆銆?/li>
3.2 鍔ㄦ€佹暟鎹簮璁剧疆
# master
spring.datasource.master.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.master.jdbc-url=jdbc:mysql://localhost:3306/mytest?useSSL=false&serverTimezone=GMT%2B8&characterEncoding=UTF-8
spring.datasource.master.username=root
spring.datasource.master.password=111111
# slave
spring.datasource.slave.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.slave.jdbc-url=jdbc:mysql://localhost:3306/my_test1?useSSL=false&serverTimezone=GMT%2B8&characterEncoding=UTF-8
spring.datasource.slave.username=root
spring.datasource.slave.password=111111
@Configuration
@PropertySource("classpath:config/jdbc.properties")
@MapperScan(basePackages = "me.mason.demo.dynamicdatasource.mapper")
public class DynamicDataSourceConfig {
@Bean(DataSourceConstants.DS_KEY_MASTER)
@ConfigurationProperties(prefix = "spring.datasource.master")
public DataSource masterDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(DataSourceConstants.DS_KEY_SLAVE)
@ConfigurationProperties(prefix = "spring.datasource.slave")
public DataSource slaveDataSource() {
return DataSourceBuilder.create().build();
}
}
娉ㄦ剰锛?/p>
- 姝ゅ浣跨敤
PropertySource
鎸囧畾閰嶇疆鏂囦欢锛?code>ConfigurationProperties 鎸囧畾鏁版嵁婧愰厤缃墠缂€
- 浣跨敤
MapperScan
鎸囧畾鍖咃紝鑷姩娉ㄥ叆鐩稿簲鐨?mapper 绫汇€?/li>
- 鎶婃暟鎹簮甯搁噺鍐欏湪
DataSourceConstants
绫讳腑
- 浠庢閰嶇疆鍙互鐪嬪埌锛屽凡缁忔妸 SqlSessionFactory 杩欎釜閰嶇疆浠庝唬鐮佷腑鎿﹂櫎锛岀洿鎺ヤ娇鐢?Spring Boot 鑷姩閰嶇疆鐨?SqlSessionFactory 鍗冲彲锛屾棤闇€鎴戜滑鑷繁閰嶇疆銆?/li>
3.2 鍔ㄦ€佹暟鎹簮璁剧疆
娉ㄦ剰锛?/p>
- 姝ゅ浣跨敤
PropertySource
鎸囧畾閰嶇疆鏂囦欢锛?code>ConfigurationProperties 鎸囧畾鏁版嵁婧愰厤缃墠缂€ - 浣跨敤
MapperScan
鎸囧畾鍖咃紝鑷姩娉ㄥ叆鐩稿簲鐨?mapper 绫汇€?/li> - 鎶婃暟鎹簮甯搁噺鍐欏湪
DataSourceConstants
绫讳腑 - 浠庢閰嶇疆鍙互鐪嬪埌锛屽凡缁忔妸 SqlSessionFactory 杩欎釜閰嶇疆浠庝唬鐮佷腑鎿﹂櫎锛岀洿鎺ヤ娇鐢?Spring Boot 鑷姩閰嶇疆鐨?SqlSessionFactory 鍗冲彲锛屾棤闇€鎴戜滑鑷繁閰嶇疆銆?/li>
鍓嶉潰鐨勯厤缃凡鎶婂涓暟鎹簮娉ㄥ叆鍒?Spring 涓紝鎺ョ潃瀵瑰姩鎬佹暟鎹簮杩涜閰嶇疆銆?/p>
3.2.1 鍔ㄦ€佹暟鎹簮閰嶇疆
** 锛?锛?娣诲姞jdbc渚濊禆 **
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
** 锛?锛?娣诲姞鍔ㄦ€佹暟鎹簮绫?**
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
// 姝ゅ鏆傛椂杩斿洖鍥哄畾 master 鏁版嵁婧? 鍚庨潰鎸夊姩鎬佺瓥鐣ヤ慨鏀? return DataSourceConstants.DS_KEY_MASTER;
}
}
娉ㄦ剰锛?/p>
- 缁ф壙鎶借薄绫?
AbstractRoutingDataSource
锛岄渶瑕佸疄鐜版柟娉?determineCurrentLookupKey
锛屽嵆璺敱绛栫暐銆?/li>- 鍔ㄦ€佽矾鐢辩瓥鐣ヤ笅涓€姝ュ疄鐜帮紝褰撳墠绛栫暐鐩存帴杩斿洖 master 鏁版嵁婧?/li>
锛?锛?璁剧疆鍔ㄦ€佹暟鎹簮涓轰富鏁版嵁婧?/strong>
鍦ㄥ墠闈㈢殑鏁版嵁婧愰厤缃枃浠?DynamicDataSourceConfig
涓紝娣诲姞浠ヤ笅浠g爜锛?/p>
@Bean
@Primary
public DataSource dynamicDataSource() {
Map<Object, Object> dataSourceMap = new HashMap<>(2);
dataSourceMap.put(DataSourceConstants.DS_KEY_MASTER, masterDataSource());
dataSourceMap.put(DataSourceConstants.DS_KEY_SLAVE, slaveDataSource());
//璁剧疆鍔ㄦ€佹暟鎹簮
DynamicDataSource dynamicDataSource = new DynamicDataSource();
dynamicDataSource.setTargetDataSources(dataSourceMap);
dynamicDataSource.setDefaultTargetDataSource(masterDataSource());
return dynamicDataSource;
}
- 浣跨敤 Map 淇濆瓨澶氫釜鏁版嵁婧愶紝骞惰缃埌鍔ㄦ€佹暟鎹簮瀵硅薄涓€?/li>
- 璁剧疆榛樿鐨勬暟鎹簮鏄?master 鏁版嵁婧?/li>
- 浣跨敤娉ㄨВ
Primary
浼樺厛浠庡姩鎬佹暟鎹簮涓幏鍙?/li>
鍚屾椂锛岄渶瑕佸湪 DynamicDataSourceConfig
涓紝鎺掗櫎 DataSourceAutoConfiguration
鐨勮嚜鍔ㄩ厤缃紝鍚﹀垯 浼氬嚭鐜?code>The dependencies of some of the beans in the application context form a cycle鐨勯敊璇€?/p>
@EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class })
public class DynamicDataSourceContextHolder {
/**
* 鍔ㄦ€佹暟鎹簮鍚嶇О涓婁笅鏂? */
private static final ThreadLocal<String> DATASOURCE_CONTEXT_KEY_HOLDER = new ThreadLocal<>();
/**
* 璁剧疆/鍒囨崲鏁版嵁婧? */
public static void setContextKey(String key){
DATASOURCE_CONTEXT_KEY_HOLDER.set(key);
}
/**
* 鑾峰彇鏁版嵁婧愬悕绉? */
public static String getContextKey(){
String key = DATASOURCE_CONTEXT_KEY_HOLDER.get();
return key == null?DataSourceConstants.DS_KEY_MASTER:key;
}
/**
* 鍒犻櫎褰撳墠鏁版嵁婧愬悕绉? */
public static void removeContextKey(){
DATASOURCE_CONTEXT_KEY_HOLDER.remove();
}
浠?DATASOURCE_CONTEXT_KEY_HOLDER 瀛樺偍闇€瑕佷娇鐢ㄦ暟鎹簮 key
getContextKey 鏃讹紝鑻?key 涓虹┖锛岄粯璁よ繑鍥?master
浠?DATASOURCE_CONTEXT_KEY_HOLDER 瀛樺偍闇€瑕佷娇鐢ㄦ暟鎹簮 key
getContextKey 鏃讹紝鑻?key 涓虹┖锛岄粯璁よ繑鍥?master
锛?锛?璁剧疆鍔ㄦ€佹暟鎹?DynamicDataSource
璺敱绛栫暐
鎴戜滑闇€瑕佽揪鍒扮殑璺敱绛栫暐鏄紝褰撹缃暟鎹簮 key 鍒颁笂涓嬫枃锛屽垯浠庝笂涓嬫枃涓緱鍒版鏁版嵁婧?key 锛屼粠鑰岀煡閬撲娇鐢ㄦ瀵瑰簲鐨勬暟鎹簮銆傚洜姝わ紝淇敼鍓嶉潰 DynamicDataSource
鐨?determineCurrentLookupKey
鏂规硶濡備笅锛?/p>
@Override
protected Object determineCurrentLookupKey() {
return DynamicDataSourceContextHolder.getContextKey();
}
3.2.3 鍔ㄦ€佹暟鎹簮浣跨敤
鏈変簡涓婇潰鐨勫姩鎬佽矾鐢遍€夋嫨锛屽垯涓嶉渶瑕佸儚涔嬪墠鐨勫濂楁暟鎹簮閭f牱锛宮apper銆乪ntity銆乻ervice绛夐兘鍐欎竴濂楃浉鍚岄€昏緫鐨勪唬鐮侊紝鍥犱负鏄富浠庯紝涓€鑸潵璇存暟鎹簱缁撴瀯鏄竴鑷寸殑锛屽彧闇€瑕佷竴濂梕ntity銆乵apper銆乻ervice鍗冲彲锛屽湪闇€瑕佸湪涓嶅悓鐨勬暟鎹簮杩涜鎿嶄綔鏃讹紝鐩存帴瀵逛笂涓嬫枃杩涜璁剧疆鍗冲彲銆傚涓嬶細
@RestController
@RequestMapping("/user")
public class TestUserController {
@Autowired
private TestUserMapper testUserMapper;
/**
* 鏌ヨ鍏ㄩ儴
*/
@GetMapping("/listall")
public Object listAll() {
int initSize = 2;
Map<String, Object> result = new HashMap<>(initSize);
//榛樿master鏌ヨ
QueryWrapper<TestUser> queryWrapper = new QueryWrapper<>();
List<TestUser> resultData = testUserMapper.selectAll(queryWrapper.isNotNull("name"));
result.put(DataSourceConstants.DS_KEY_MASTER, resultData);
//鍒囨崲鏁版嵁婧愶紝鍦╯lave鏌ヨ
DynamicDataSourceContextHolder.setContextKey(DataSourceConstants.DS_KEY_SLAVE);
List<TestUser> resultDataSlave = testUserMapper.selectList(null);
result.put(DataSourceConstants.DS_KEY_SLAVE, resultDataSlave);
//鎭㈠鏁版嵁婧? DynamicDataSourceContextHolder.removeContextKey();
//杩斿洖鏁版嵁
return ResponseResult.success(result);
}
}
- 榛樿鏄娇鐢?master 鏁版嵁婧愭煡璇?/li>
- 浣跨敤涓婁笅鏂囩殑 setContextKey 鏉ュ垏鎹㈡暟鎹簮锛屼娇鐢ㄥ畬鍚庝娇鐢?removeContextKey 杩涜鎭㈠
java寮€鍙戝繀瀛︾煡璇?鍔ㄦ€佷唬鐞?/a>銆嬨€傚湪 Spring 涓紝AOP 鐨勫疄鐜颁篃鏄熀浜庡姩鎬佷唬鐞嗙殑銆傛澶勶紝鎴戜滑甯屾湜閫氳繃娉ㄨВ鐨勬柟寮忔寚瀹氬嚱鏁伴渶瑕佺殑鏁版嵁婧愶紝浠庤€屾秷闄ゆ暟鎹簮鍒囨崲鏃朵骇鍝佺殑妯℃澘浠g爜銆?/p>
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface DS {
/**
* 鏁版嵁婧愬悕绉? */
String value() default DataSourceConstants.DS_KEY_MASTER;
}
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface DS {
/**
* 鏁版嵁婧愬悕绉? */
String value() default DataSourceConstants.DS_KEY_MASTER;
}
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
锛?锛?瀹氫箟鍒囬潰
@Aspect
@Component
public class DynamicDataSourceAspect {
@Pointcut("@annotation(me.mason.demo.dynamicdatasource.annotation.DS)")
public void dataSourcePointCut(){
}
@Around("dataSourcePointCut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
String dsKey = getDSAnnotation(joinPoint).value();
DynamicDataSourceContextHolder.setContextKey(dsKey);
try{
return joinPoint.proceed();
}finally {
DynamicDataSourceContextHolder.removeContextKey();
}
}
/**
* 鏍规嵁绫绘垨鏂规硶鑾峰彇鏁版嵁婧愭敞瑙? */
private DS getDSAnnotation(ProceedingJoinPoint joinPoint){
Class<?> targetClass = joinPoint.getTarget().getClass();
DS dsAnnotation = targetClass.getAnnotation(DS.class);
// 鍏堝垽鏂被鐨勬敞瑙o紝鍐嶅垽鏂柟娉曟敞瑙? if(Objects.nonNull(dsAnnotation)){
return dsAnnotation;
}else{
MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature();
return methodSignature.getMethod().getAnnotation(DS.class);
}
}
}
- 娉ㄨВ Pointcut 浣跨敤
annotation
鎸囧畾娉ㄨВ- 娉ㄨВ Around 浣跨敤鐜粫閫氱煡澶勭悊锛屼娇鐢ㄤ笂涓嬫枃杩涜瀵逛娇鐢ㄦ敞瑙?
DS
鐨勫€艰繘琛屾暟鎹簮鍒囨崲锛屽鐞嗗畬鍚庯紝鎭㈠鏁版嵁婧愩€?/li>
/**
* 鏌ヨmaster搴揢ser
*/
@DS(DataSourceConstants.DS_KEY_MASTER)
public List<TestUser> getMasterUser(){
QueryWrapper<TestUser> queryWrapper = new QueryWrapper<>();
return testUserMapper.selectAll(queryWrapper.isNotNull("name"));
}
/**
* 鏌ヨslave搴揢ser
*/
@DS(DataSourceConstants.DS_KEY_SLAVE)
public List<TestUser> getSlaveUser(){ return testUserMapper.selectList(null); }
杩欐牱瀹氫箟鍚庯紝鍦?controller 灞傜殑澶勭悊灏卞彲浠ュ彉鎴愶細
@GetMapping("/listall")
public Object listAll() {
int initSize = 2;
Map<String, Object> result = new HashMap<>(initSize);
//榛樿master鏁版嵁婧愭煡璇? List<TestUser> masterUser = testUserService.getMasterUser();
result.put(DataSourceConstants.DS_KEY_MASTER, masterUser);
//浠巗lave鏁版嵁婧愭煡璇? List<TestUser> slaveUser = testUserService.getSlaveUser();
result.put(DataSourceConstants.DS_KEY_SLAVE, slaveUser);
//杩斿洖鏁版嵁
return ResponseResult.success(result);
}
鐢辨鍙锛屽凡缁忔妸鏁版嵁搴撳垏鎹㈢殑妯℃澘浠g爜娑堥櫎锛屽彧闇€瑕佸叧娉ㄤ笟鍔¢€昏緫澶勭悊鍗冲彲銆傝繖灏辨槸AOP鐨勫ソ澶勩€?/p>
鍔ㄦ€佹暟鎹簮鐨勬彃浠?/a>锛屾湁鍏磋叮鐨勫皬浼欎即涔熷彲浠ユ牴鎹畠鐨勫畼鏂规枃妗h繘琛屽疄楠屼娇鐢ㄣ€?/p>
瀵逛簬鍔ㄦ€佹暟鎹簮锛岃繕鏈夊摢浜涘湴鏂归渶瑕佽€冭檻鎴栬€呰鍊煎緱鏀硅繘鐨勫湴鏂瑰憿锛?/p>
- 浜嬪姟濡備綍澶勭悊锛熷叾瀹炲湪寮€鍙戜腑搴旇灏介噺閬垮厤璺ㄥ簱浜嬪姟锛屼絾濡傛灉閬垮厤涓嶄簡锛屽垯闇€瑕佷娇鐢ㄥ垎甯冨紡浜嬪姟銆?/li>
- 瀵逛簬褰撳墠鐨勫姩鎬佹暟鎹簮锛岀浉瀵规潵璇磋繕鏄浐瀹氱殑鏁版嵁婧愶紙濡備竴涓讳竴浠庯紝涓€涓诲浠庣瓑锛夛紝鍗冲湪缂栫爜鏃跺凡缁忕‘瀹氱殑鏁版嵁搴撴暟閲忥紝鍙槸鍦ㄥ叿浣撲娇鐢ㄥ摢涓€涓椂杩涜鍔ㄦ€佸鐞嗐€傚鏋滄暟鎹簮鏈韩骞朵笉纭畾锛屾垨鑰呰闇€瑕佹牴鎹敤鎴疯緭鍏ユ潵杩炴帴鏁版嵁搴擄紝杩欐椂锛屽浣曞鐞嗗憿锛熻繖绉嶆儏鍐靛嚭鐜板緱姣旇緝澶氱殑鏄湪瀵瑰涓暟鎹簱杩涜绠$悊鏃剁殑澶勭悊銆傝繖绉嶆儏鍐碉紝鎴戝皢鍦ㄤ笅涓€绡囨枃绔犱腑杩涜璁茶В锛屾垜鎶婂畠鍙仛"鍙傛暟鍖栧彉鏇存暟鎹簮"銆?/li>
5. 鎬荤粨
鏈枃瀵瑰姩鎬佹暟鎹簮鐨勫疄鐜拌繘琛屼簡璁茶В锛屼富瑕佹槸鍔ㄦ€佹暟鎹簮鐨勯厤缃€佸疄鐜般€佷娇鐢紝鍙﹀杩樹娇鐢?AOP 娑堥櫎鍒囨崲鏁版嵁婧愭椂鐨勬ā鏉夸唬鐮侊紝浣挎垜浠紑鍙戜笓娉ㄤ簬涓氬姟浠g爜锛屾渶鍚庡鍔ㄦ€佹暟鎹簮鐨勮繘琛屼簡涓€涓嬫墿灞曟€濊€冦€傚笇鏈涘皬浼欎即浠彲浠ユ帉鎻″姩鎬佹暟鎹簮鐨勫鐞嗐€?/p>
鏈枃閰嶅鐨勭ず渚嬶紝绀轰緥浠g爜锛屾湁鍏磋叮鐨勫彲浠ヨ繍琛岀ず渚嬫潵鎰熷彈涓€涓嬨€?/p>
Spring涓讳粠鏁版嵁搴撶殑閰嶇疆鍜屽姩鎬佹暟鎹簮鍒囨崲鍘熺悊: https://www.liaoxuefeng.com/article/1182502273240832
https://juejin.im/post/5b790a866fb9a019ea01f38c
https://juejin.im/post/5cb0023d5188250df17d4ffc
https://juejin.im/post/5a927d23f265da4e7e10d740
鎼炲畾SpringBoot澶氭暟鎹簮(1)锛氬濂楁簮绛栫暐
鎴戠殑鍏紬鍙凤紙鎼滅储Mason鎶€鏈褰?/code>锛夛紝鑾峰彇鏇村鎶€鏈褰曪細
以上是关于鎼炲畾SpringBoot澶氭暟鎹簮锛氬姩鎬佹暟鎹簮的主要内容,如果未能解决你的问题,请参考以下文章
08.@Scheduled瀹氭椂浠诲姟銆佹暣鍚坖dbcTemplate銆乵ybatis鍖哄垎澶氭暟鎹簮