生成 maven 项目结构
包含的资源目录如下
pom文件中指定生成格式
<packaging>jar</packaging>
创建对应的自定义配置对象
@ConfigurationProperties(prefix = "app.huitongredis")
public class HuitongRedisProperties {
/**
* 环境
*/
private String env = "dev";
//"redis-config/dev";
/**
* 证书文件路径
*/
private String basedir;
/**
* redis host port list, format=host:port. use ',' sep
*/
private String hostListString;
/**
* 超时时间秒
*/
private int timeout = 30;
/**
* 最长等待时间秒
*/
private int maxWait = 30;
private int minIdle = 0;
private int maxIdle = 1;
}
创建 autoConfiguration 配置类
此处需要将注入 spring context 的 bean 注入进来
读取资源文件
如果使用 file 方式是读取不到资源文件的,目标项目中依赖的 starter 只是一个 jar包,无法读取这个jar包下的资源文件,需要使用如下方式来读取
使用如下方式 类似于mybatis 读取 mapper 的方式读取resources目录下的资源文件
PathMatchingResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver(HuitongRedisAutoConfiguration.class.getClassLoader());
patternResolver.getResource(srcFile).getInputStream(); //可以获取文件输入流
@Slf4j
@Configuration
@ConditionalOnClass(HuitongRedisProperties.class)
@EnableConfigurationProperties(HuitongRedisProperties.class)
public class HuitongRedisAutoConfiguration {
@Autowired
private HuitongRedisProperties redisProperties;
@Bean
@Primary
public RedisConnectionFactory redisConnectionFactory() {
System.setProperty("java.security.krb5.conf", getKrb5Path());
AuthConfiguration authConfiguration = new AuthConfiguration(getKeytabPath(), redisProperties.getPrincipal());
GlobalConfig.setAuthConfiguration(authConfiguration);
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxWaitMillis(Duration.ofSeconds(redisProperties.getMaxWait()).toMillis());
poolConfig.setMaxIdle(redisProperties.getMaxIdle());
poolConfig.setMinIdle(redisProperties.getMinIdle());
JedisClientConfiguration clientConfig = JedisClientConfiguration.builder()
.usePooling()
.poolConfig(poolConfig)
.and()
.readTimeout(Duration.ofSeconds(redisProperties.getTimeout()))
.connectTimeout(Duration.ofSeconds(redisProperties.getTimeout())).build();
RedisClusterConfiguration clusterConfig = new RedisClusterConfiguration(getRedisNodeSet());
return new JedisConnectionFactory(clusterConfig, clientConfig);
}
@Bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
RedisTemplate<Object, Object> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
public String getKrb5Path() {
if (StringUtils.isBlank(redisProperties.getBasedir())) {
String baseDirByEnvname = ConfigConst.Env.getBaseDirByEnvname(redisProperties.getEnv());
String srcFile = baseDirByEnvname + File.separator + ConfigConst.KRB5_FILENAME;
PathMatchingResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver(HuitongRedisAutoConfiguration.class.getClassLoader());
String desFile = getTempDirPath() + ConfigConst.KRB5_FILENAME;
try {
FileUtils.copyInputStreamToFile(patternResolver.getResource(srcFile).getInputStream(), new File(desFile));
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("init HW redis krb5 error", e);
}
log.info("dest file: " + desFile);
return desFile;
} else {
return redisProperties.getBasedir() + File.separator + ConfigConst.KRB5_FILENAME;
}
}
private String getKeytabPath() {
if (StringUtils.isBlank(redisProperties.getBasedir())) {
String baseDirByEnvname = ConfigConst.Env.getBaseDirByEnvname(redisProperties.getEnv());
String srcFile = baseDirByEnvname + File.separator + ConfigConst.KEYTAB_FILENAME;
PathMatchingResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver(HuitongRedisAutoConfiguration.class.getClassLoader());
String desFile = getTempDirPath() + ConfigConst.KEYTAB_FILENAME;
try {
FileUtils.copyInputStreamToFile(patternResolver.getResource(srcFile).getInputStream(), new File(desFile));
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("init HW redis keytab error", e);
}
log.info("dest file: " + desFile);
return desFile;
} else {
return redisProperties.getBasedir() + File.separator + ConfigConst.KEYTAB_FILENAME;
}
}
private String getTempDirPath() {
String tempPath = System.getProperty(ConfigConst.TEMP_DIR_PROPERTY);
if (!(tempPath.endsWith("/") || tempPath.endsWith("\\"))) {
return tempPath + File.separator;
}
return tempPath;
}
private Set<String> getRedisNodeSet() {
Set<String> result = null;
if (StringUtils.isBlank(redisProperties.getHostListString())) {
result = parseHostListString(ConfigConst.Env.getHostAndPortSetByEnvname(redisProperties.getEnv()));
} else {
result = parseHostListString(redisProperties.getHostListString());
}
return result;
}
public static Set<String> parseHostListString(String hostListString) {
Set<String> result = new HashSet<>();
if (StringUtils.isNotBlank(hostListString)) {
result.addAll(Arrays.asList(hostListString.split(",")));
}
return result;
}
}
为了使使用方方便使用,创建自定义 Enable,使用方只需引入对应的enable就可以直接使用
@Import 功能是将需要导入的自动化配置类导入,使用方可以将我们注入的bean注入到使用系统spring环境中
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(HuitongRedisAutoConfiguration.class)
public @interface EnableHuitongRedis {
}
最重要的要想 springboot 能够自动配置需要将自动化配置类配置到 spring.factories 文件中
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.huitong.config.HuitongRedisAutoConfiguration