日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

autobahn-java-master,禁用自动配置

發(fā)布時間:2023/12/29 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 autobahn-java-master,禁用自动配置 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Spring Boot大量使用自動配置和默認配置,極大地減少了代碼,通常只需要加上幾個注解,并按照默認規(guī)則設定一下必要的配置即可。例如,配置JDBC,默認情況下,只需要配置一個spring.datasource:

spring:

datasource:

url: jdbc:hsqldb:file:testdb

username: sa

password:

dirver-class-name: org.hsqldb.jdbc.JDBCDriver

Spring Boot就會自動創(chuàng)建出DataSource、JdbcTemplate、DataSourceTransactionManager,非常方便。

但是,有時候,我們又必須要禁用某些自動配置。例如,系統(tǒng)有主從兩個數(shù)據(jù)庫,而Spring Boot的自動配置只能配一個,怎么辦?

這個時候,針對DataSource相關的自動配置,就必須關掉。我們需要用exclude指定需要關掉的自動配置:

@SpringBootApplication

// 啟動自動配置,但排除指定的自動配置:

@EnableAutoConfiguration(exclude = DataSourceAutoConfiguration.class)

public class Application {

...

}

現(xiàn)在,Spring Boot不再給我們自動創(chuàng)建DataSource、JdbcTemplate和DataSourceTransactionManager了,要實現(xiàn)主從數(shù)據(jù)庫支持,怎么辦?

讓我們一步一步開始編寫支持主從數(shù)據(jù)庫的功能。首先,我們需要把主從數(shù)據(jù)庫配置寫到application.yml中,仍然按照Spring Boot默認的格式寫,但datasource改為datasource-master和datasource-slave:

spring:

datasource-master:

url: jdbc:hsqldb:file:testdb

username: sa

password:

dirver-class-name: org.hsqldb.jdbc.JDBCDriver

datasource-slave:

url: jdbc:hsqldb:file:testdb

username: sa

password:

dirver-class-name: org.hsqldb.jdbc.JDBCDriver

注意到兩個數(shù)據(jù)庫實際上是同一個庫。如果使用MySQL,可以創(chuàng)建一個只讀用戶,作為datasource-slave的用戶來模擬一個從庫。

下一步,我們分別創(chuàng)建兩個HikariCP的DataSource:

public class MasterDataSourceConfiguration {

@Bean("masterDataSourceProperties")

@ConfigurationProperties("spring.datasource-master")

DataSourceProperties dataSourceProperties() {

return new DataSourceProperties();

}

@Bean("masterDataSource")

DataSource dataSource(@Autowired @Qualifier("masterDataSourceProperties") DataSourceProperties props) {

return props.initializeDataSourceBuilder().build();

}

}

public class SlaveDataSourceConfiguration {

@Bean("slaveDataSourceProperties")

@ConfigurationProperties("spring.datasource-slave")

DataSourceProperties dataSourceProperties() {

return new DataSourceProperties();

}

@Bean("slaveDataSource")

DataSource dataSource(@Autowired @Qualifier("slaveDataSourceProperties") DataSourceProperties props) {

return props.initializeDataSourceBuilder().build();

}

}

注意到上述class并未添加@Configuration和@Component,要使之生效,可以使用@Import導入:

@SpringBootApplication

@EnableAutoConfiguration(exclude = DataSourceAutoConfiguration.class)

@Import({ MasterDataSourceConfiguration.class, SlaveDataSourceConfiguration.class})

public class Application {

...

}

此外,上述兩個DataSource的Bean名稱分別為masterDataSource和slaveDataSource,我們還需要一個最終的@Primary標注的DataSource,它采用Spring提供的AbstractRoutingDataSource,代碼實現(xiàn)如下:

class RoutingDataSource extends AbstractRoutingDataSource {

@Override

protected Object determineCurrentLookupKey() {

// 從ThreadLocal中取出key:

return RoutingDataSourceContext.getDataSourceRoutingKey();

}

}

RoutingDataSource本身并不是真正的DataSource,它通過Map關聯(lián)一組DataSource,下面的代碼創(chuàng)建了包含兩個DataSource的RoutingDataSource,關聯(lián)的key分別為masterDataSource和slaveDataSource:

public class RoutingDataSourceConfiguration {

@Primary

@Bean

DataSource dataSource(

@Autowired @Qualifier("masterDataSource") DataSource masterDataSource,

@Autowired @Qualifier("slaveDataSource") DataSource slaveDataSource) {

var ds = new RoutingDataSource();

// 關聯(lián)兩個DataSource:

ds.setTargetDataSources(Map.of(

"masterDataSource", masterDataSource,

"slaveDataSource", slaveDataSource));

// 默認使用masterDataSource:

ds.setDefaultTargetDataSource(masterDataSource);

return ds;

}

@Bean

JdbcTemplate jdbcTemplate(@Autowired DataSource dataSource) {

return new JdbcTemplate(dataSource);

}

@Bean

DataSourceTransactionManager dataSourceTransactionManager(@Autowired DataSource dataSource) {

return new DataSourceTransactionManager(dataSource);

}

}

仍然需要自己創(chuàng)建JdbcTemplate和PlatformTransactionManager,注入的是標記為@Primary的RoutingDataSource。

這樣,我們通過如下的代碼就可以切換RoutingDataSource底層使用的真正的DataSource:

RoutingDataSourceContext.setDataSourceRoutingKey("slaveDataSource");

jdbcTemplate.query(...);

只不過寫代碼切換DataSource即麻煩又容易出錯,更好的方式是通過注解配合AOP實現(xiàn)自動切換,這樣,客戶端代碼實現(xiàn)如下:

@Controller

public class UserController {

@RoutingWithSlave //

@GetMapping("/profile")

public ModelAndView profile(HttpSession session) {

...

}

}

實現(xiàn)上述功能需要編寫一個@RoutingWithSlave注解,一個AOP織入和一個ThreadLocal來保存key。由于代碼比較簡單,這里我們不再詳述。

如果我們想要確認是否真的切換了DataSource,可以覆寫determineTargetDataSource()方法并打印出DataSource的名稱:

class RoutingDataSource extends AbstractRoutingDataSource {

...

@Override

protected DataSource determineTargetDataSource() {

DataSource ds = super.determineTargetDataSource();

logger.info("determin target datasource: {}", ds);

return ds;

}

}

訪問不同的URL,可以在日志中看到兩個DataSource,分別是HikariPool-1和hikariPool-2:

2020-06-14 17:55:21.676 INFO 91561 --- [nio-8080-exec-7] c.i.learnjava.config.RoutingDataSource : determin target datasource: HikariDataSource (HikariPool-1)

2020-06-14 17:57:08.992 INFO 91561 --- [io-8080-exec-10] c.i.learnjava.config.RoutingDataSource : determin target datasource: HikariDataSource (HikariPool-2)

我們用一個圖來表示創(chuàng)建的DataSource以及相關Bean的關系:

┌────────────────────┐ ┌──────────────────┐

│@Primary │

│RoutingDataSource │ └──────────────────┘

│ ┌────────────────┐ │ ┌──────────────────┐

│ │MasterDataSource│ │

│ └────────────────┘ │ │TransactionManager│

│ ┌────────────────┐ │ └──────────────────┘

│ │SlaveDataSource │ │

│ └────────────────┘ │

└────────────────────┘

注意到DataSourceTransactionManager和JdbcTemplate引用的都是RoutingDataSource,所以,這種設計的一個限制就是:在一個請求中,一旦切換了內部數(shù)據(jù)源,在同一個事務中,不能再切到另一個,否則,DataSourceTransactionManager和JdbcTemplate操作的就不是同一個數(shù)據(jù)庫連接。

練習

小結

可以通過@EnableAutoConfiguration(exclude = {...})指定禁用的自動配置;

可以通過@Import({...})導入自定義配置。

總結

以上是生活随笔為你收集整理的autobahn-java-master,禁用自动配置的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。