我想用一个例子来说明我的真实的问题,
这是一个分布式锁的小项目,其目的是通过属性文件配置分布式锁,使用时不需要考虑其实现。
您可以像这样配置分布式锁属性文件
dlock:
list: # this is a Map List
- namespace: redis-dlock-1
type: redis
config: # the config includes specific impl properties, here is redisson
...
- namespace: db-dlock-1
type: database
config: # here is database config
...
- namespace: zk-dlock-1
type: zookeeper
config: # here is curator config
...
...
在项目中使用分布式锁时,您只需导入依赖项,创建配置文件,并在项目中使用Annotation或API,如下所示
// this is a user method
@DistributedLock(namespace="redis-dlock-1", tryWait=3000, fair=false)
public void invoke(Object[] params) {
......
}
public void invoke(Object[] params) {
DLock lock = DLockSupport.getDLock(/* namespace = */ "db-dlock-1", /* fair = */false);
......
if (lock.tryLock(3000)) {
...... // do bussiness
lock.unlock();
}
......
}
它很容易制作和使用,但正如我提到的,分布式锁有3个impl:database, zookeeper, redis
,为了避免用户主动选择其impl,它们位于同一个项目com.example.dlock:distributed-lock
中
distributed-lock
|
impl
|
redis
zookeeper
database
但是我发现一个问题,即使我的项目几乎只使用redis impl,导入分布式锁也会导致导入数据库和zookeeper依赖,这是我不想看到的
换句话说,我想让库的impl只有在它的基本依赖已经被用户项目导入时才有效。也就是说,如果只有redison(redis),那么zookeeper和数据库是无效的,如果有redison(redis)和数据库,那么使用zookeeper是无效的,如果env有所有的impl依赖,那么你可以使用任何分布式锁的impl
我的配置设计是这样的:
@Configuration
@Import(RedisDLockConfiguration.class,
ZookeeperDLockConfiguration.class,
DatabaseDLockConfiguration.class)
public class DLockAutoConfiguration { }
@ConditionalOnClass({RedisTemplate.class, RedissonClient.class})
@EnableConfigurationProperties(RedisDLockProperties.class)
public class RedisDLockConfiguration {
......
}
@ConditionalOnClass({Zookeeper.class, CuratorFramework.class})
@EnableConfigurationProperties(ZookeeperDLockProperties.class)
public class ZookeeperDLockConfiguration {
......
}
@ConditionalOnClass({JdbcTemplate.class, Connection.class})
@EnableConfigurationProperties(DatabaseDLockProperties.class)
public class DatabaseDLockConfiguration {
......
}
因此,在我的赋值中,如果用户classpath包含RedisTemplate.class,RedissonClient.class,则将启用redis-dlock,与数据库和zookeeper相同,instead if user lack some class, and it should be ignored and ok, but actually i got missing class error
我的真实的问题就像这个例子一样,我继承了一个旧的spring-cloud lib系统,并命令升级到2021.0.X,系统源代码在一个普通模块中包含一个ZuulFilter,所以我将其替换为springcloud-gateway的GlobalFilter,我以为它会在gateway导入的环境中启用,而在普通env中禁用,但我错了,它导入了很多gateway的类和bean,这太重了,无法接受
有没有办法实现目标?
1条答案
按热度按时间o7jaxewo1#
将
distributed-lock
的每个实现移动到一个单独的Maven模块中,这样应用程序就可以只在它们真正想要使用的模块上声明依赖项。在应用程序中,避免显式导入distributed-lock
的3个实现的配置类:可以使用@ComponentScan
或@Autoconfiguration
。