读写分离的java redis 接口_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 读写分离的java redis 接口

读写分离的java redis 接口

 2020/5/28 18:36:20  xugangqiang  程序员俱乐部  我要评论(0)
  • 摘要:目的:为了spring上下文添加读写分离的接口,可以在启动后自动注入redis只读接口或可读写接口1.定义一个相关的functionalinterface-在springboot的启动类里面要用到(@EnableDynamicKeyValueServiceCreation)@Retention(value=RetentionPolicy.RUNTIME)@Import(KeyValueServiceRegister.class
  • 标签:Java 接口

?目的:为了spring上下文添加读写分离的接口,可以在启动后自动注入redis只读接口或可读写接口

?

1. 定义一个相关的functional interface - 在spring boot的启动类里面要用到(@EnableDynamicKeyValueServiceCreation)

@Retention(value = RetentionPolicy.RUNTIME)

@Import(KeyValueServiceRegister.class)

public @interface EnableDynamicKeyValueServiceCreation {

}

2. 定义只读接口和可读写接口
public interface KeyValueReadService { String get(String key); ...}

public interface KeyValueReadWriteService extends KeyValueReadService { void set(String key, String value); ..}

?

3. 实现类

public class RedisConfigInfo {

? ? private String hostName;

? ? private int port;

? ? private String password;

? ? private JedisPoolConfig poolConfig;

}

?

public abstract class AbstractRedisOperation {

? ? private final JedisPool jedisPool;

? ? public AbstractRedisOperation (RedisConfigInfo info) { jedisPool = ...;}

}

?

public class RedisReadServiceImpl extends AbstractRedisOperation implements KeyValueReadService {

?

? ? public RedisReadServiceImpl(RedisConfigInfo temp) {

? ? ? ? super(temp);

? ? }

?

? ? @Override

? ? public String get(String key) {

? ? ? ? return stringValueOps.get(key);

? ? }

}

?

4. 通过spring去获取redis的配置信息

@Component

public class KeyValueServiceRegister implements ImportBeanDefinitionRegistrar, EnvironmentAware {

?

? ? private static Logger logger = LoggerFactory.getLogger(KeyValueServiceRegister.class);

?

? ? private Map<String, BeanDefinition> beanDefinitionMap = null;

?

? ? @Override

? ? public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,

? ? ? ? ? ? BeanDefinitionRegistry registry) {

? ? ? ? if (beanDefinitionMap == null || beanDefinitionMap.isEmpty()) {

? ? ? ? ? ? logger.warn("beanDefinitions is empty");

? ? ? ? ? ? return;

? ? ? ? }

? ? ? ? String beanName;

? ? ? ? BeanDefinition beanDefinition;

? ? ? ? for (Map.Entry<String, BeanDefinition> entry : beanDefinitionMap.entrySet()) {

? ? ? ? ? ? beanName = entry.getKey();

? ? ? ? ? ? beanDefinition = entry.getValue();

? ? ? ? ? ? registry.registerBeanDefinition(beanName, beanDefinition);

? ? ? ? }

?

? ? }

?

? ? @SuppressWarnings("rawtypes")

? ? @Override

? ? public void setEnvironment(Environment environment) {

? ? ? ? String prefix = environment.getProperty("prefix.keyvalue.cache", "kv.");

?

? ? ? ? Properties props = new Properties();

? ? ? ? MutablePropertySources propSrcs = ((AbstractEnvironment) environment).getPropertySources();

? ? ? ? StreamSupport.stream(propSrcs.spliterator(), false)

? ? ? ? ? ? ? ? .filter(ps -> ps instanceof EnumerablePropertySource)

? ? ? ? ? ? ? ? .map(ps -> ((EnumerablePropertySource) ps).getPropertyNames())

? ? ? ? ? ? ? ? .flatMap(Arrays::<String>stream).filter(name -> name.startsWith(prefix)).forEach(

? ? ? ? ? ? ? ? ? ? ? ? propName -> props.setProperty(propName, environment.getProperty(propName)));

? ? ? ??

? ? ? ? beanDefinitionMap = Collections

? ? ? ? ? ? ? ? .unmodifiableMap(KeyValueServiceHelper.buildBeanDefinitionMap(props));

? ? }

?

}

?

5. 根据配置信息构建bean

public class KeyValueServiceHelper {

?

? ? private static final String POSFIX_READ = ".r";

?

? ? private static final String POSFIX_WRITE = ".w";

?

? ? public static final Map<String, Properties> buildDataSourceMap(Properties prop) {

? ? ? ? if (prop == null || prop.isEmpty()) {

? ? ? ? ? ? return Collections.emptyMap();

? ? ? ? }

? ? ? ? Map<String, Properties> result = new HashMap<>();

? ? ? ? Set<String> keys = prop.stringPropertyNames();

? ? ? ? Properties temp;

? ? ? ? String dsName;

? ? ? ? for (String key : keys) {

? ? ? ? ? ? dsName = key;

? ? ? ? ? ? if (!isKeyValueServiceBeanName(key)) {

? ? ? ? ? ? ? ? dsName = removePosfix(key);

? ? ? ? ? ? }

? ? ? ? ? ? temp = result.get(dsName);

? ? ? ? ? ? if (temp == null) {

? ? ? ? ? ? ? ? temp = new Properties();

? ? ? ? ? ? ? ? result.put(dsName, temp);

? ? ? ? ? ? }

? ? ? ? ? ? temp.setProperty(key, prop.getProperty(key));

? ? ? ? }

? ? ? ? return result;

? ? }

?

? ? public static final boolean isKeyValueServiceBeanName(String str) {

? ? ? ? if (StringUtils.isBlank(str)) {

? ? ? ? ? ? return false;

? ? ? ? }

? ? ? ? return str.endsWith(POSFIX_READ) || str.endsWith(POSFIX_WRITE);

? ? }

?

? ? public static final String removePosfix(String str) {

? ? ? ? if (StringUtils.isBlank(str)) {

? ? ? ? ? ? return str;

? ? ? ? }

? ? ? ? int idx = str.lastIndexOf(".");

? ? ? ? if (idx == -1) {

? ? ? ? ? ? return str;

? ? ? ? }

? ? ? ? return str.substring(0, idx);

? ? }

?

? ? public static final String resolveBeanClassName(final String beanName,

? ? ? ? ? ? final String connectionStr) {

? ? ? ? if (StringUtils.isBlank(beanName)) {

? ? ? ? ? ? throw new IllegalArgumentException("bean name is blank");

? ? ? ? }

?

? ? ? ? if (StringUtils.isBlank(connectionStr)) {

? ? ? ? ? ? throw new IllegalArgumentException("connectionStr is blank");

? ? ? ? }

?

? ? ? ? if (!RedisConnectionHelper.isRedisConnectionString(connectionStr)) {

? ? ? ? ? ? throw new IllegalArgumentException("connectionStr is invalid");

? ? ? ? }

?

? ? ? ? if (beanName.endsWith(POSFIX_READ)) {

? ? ? ? ? ? return RedisReadServiceImpl.class.getName();

? ? ? ? }

? ? ? ? if (beanName.endsWith(POSFIX_WRITE)) {

? ? ? ? ? ? return RedisReadWriteServiceImpl.class.getName();

? ? ? ? }

? ? ? ? throw new IllegalArgumentException("beanName is invalid,should end with '.r' or '.w'");

? ? }

?

? ? public static final Map<String, BeanDefinition> buildBeanDefinitionMap(Properties props) {

? ? ? ? Map<String, Properties> cacheSources = buildDataSourceMap(props);

? ? ? ? if (cacheSources == null || cacheSources.isEmpty()) {

? ? ? ? ? ? return Collections.emptyMap();

? ? ? ? }

? ? ? ? BeanDefinition def;

? ? ? ? String beanName;

? ? ? ? String connectionStr;

? ? ? ? String beanClassName;

? ? ? ? Properties prop;

? ? ? ? RedisConfigInfo info;

? ? ? ? Map<String, BeanDefinition> beanMap =

? ? ? ? ? ? ? ? new HashMap<String, BeanDefinition>(cacheSources.size());

? ? ? ? for (Map.Entry<String, Properties> entry : cacheSources.entrySet()) {

? ? ? ? ? ? beanName = entry.getKey();

? ? ? ? ? ? prop = entry.getValue();

? ? ? ? ? ? connectionStr = prop.getProperty(beanName);

? ? ? ? ? ? if (!RedisConnectionHelper.isRedisConnectionString(connectionStr)) {

? ? ? ? ? ? ? ? continue;

? ? ? ? ? ? }

? ? ? ? ? ? info = RedisConnectionHelper.parseRedisConfigInfo(prop, beanName);

?

? ? ? ? ? ? def = new GenericBeanDefinition();

? ? ? ? ? ? beanClassName = KeyValueServiceHelper.resolveBeanClassName(beanName, connectionStr);

? ? ? ? ? ? def.setBeanClassName(beanClassName);

?

? ? ? ? ? ? def.getConstructorArgumentValues().addGenericArgumentValue(info);

? ? ? ? ? ? beanMap.put(beanName, def);

? ? ? ? }

? ? ? ? return beanMap;

? ? }

}

?

6. 如何使用

a. 在SpringBoot的启动类里面加上@EnableDynamicKeyValueServiceCreation

b. 配置文件里面加上读写分离的redis的配置信息 - 读的是.r结尾,可写的是.w结尾

c. 在需要只读redis的service里面, 直接注入(@KeyValueReadService (name=**.r)
d. 在需要读写redis的service里面, 直接注入(@KeyValueReadService (name=**.w)

?

上一篇: 基于jQuery+Bootstrap前端框架的.Net快速开发平台 下一篇: 没有下一篇了!
发表评论
用户名: 匿名