如何阻止Bean注入指定外部库/类?解决多DataSource注入冲突
解决外部库Optional注入冲突并保持为空的方案
核心思路
让容器中不存在无限定符的DataSource Bean,这样外部库中未指定任何限定符的@Inject Optional<DataSource>会因找不到匹配Bean而自动保持为空,同时解决多Bean冲突问题。
方案一:使用自定义限定符标记所有自定义DataSource
- 创建自定义限定符注解
@Qualifier @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE}) public @interface AppDataSource { String value(); // 用于区分不同数据源,如"read-only"、"read-and-write" }
- 修改
DataSourceFactory中的生产者方法,替换@Named为自定义限定符
@Factory public class DataSourceFactory { @Singleton @AppDataSource("read-only") public DataSource dataSource(ReadOnlyDataSourceConfig config) { HikariConfig hikariConfig = new HikariConfig(); hikariConfig.setJdbcUrl(config.getUrl()); hikariConfig.setUsername(config.getUsername()); hikariConfig.setPassword(config.getPassword()); hikariConfig.setDriverClassName(config.getDriverClassName()); return new HikariDataSource(hikariConfig); } @Singleton @AppDataSource("read-and-write") public DataSource dataSource(ReadAndWriteDataSourceConfig config) { HikariConfig hikariConfig = new HikariConfig(); hikariConfig.setJdbcUrl(config.getUrl()); hikariConfig.setUsername(config.getUsername()); hikariConfig.setPassword(config.getPassword()); hikariConfig.setDriverClassName(config.getDriverClassName()); return new HikariDataSource(hikariConfig); } }
所有自定义DataSource Bean都带有@AppDataSource限定符后,外部库的@Inject Optional<DataSource>因未指定限定符,无法匹配任何Bean,最终Optional会保持为空,同时解决了多Bean候选的冲突错误。
方案二:CDI环境下使用@Vetoed排除默认匹配(可选)
如果不想修改生产者方法,可通过CDI的@Vetoed注解标记自定义DataSource Bean,阻止它们被无限定符的注入点匹配:
@Factory public class DataSourceFactory { @Singleton @Named("read-only") @Vetoed public DataSource dataSource(ReadOnlyDataSourceConfig config) { // 原有代码不变 } @Singleton @Named("read-and-write") @Vetoed public DataSource dataSource(ReadAndWriteDataSourceConfig config) { // 原有代码不变 } }
注:@Vetoed会让Bean仅能被明确指定限定符(如@Named)的注入点匹配,无限定符的外部库注入点将无法找到它们,Optional因此为空。
内容的提问来源于stack exchange,提问作者hfg124g76g1
相关产品推荐
相关产品推荐

