package -------------.data.source.impl;
import -------------.util.MD5;
import -------------.dataMapping.SourceSys;
import -------------.data.source.RedisSourceService;
import -------------.dataMapping.SourceSysService;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.*;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by 11273 on 2018/1/8.
*/
@Service
@Configuration
public class RedisSourceServiceImpl implements RedisSourceService,ApplicationContextAware,ApplicationListener{
@Value("${spring.sjzx.redis.host}")
private String host;
@Value("${spring.sjzx.redis.password}")
private String password;
@Value("${spring.sjzx.redis.port}")
private int port;
@Value("${spring.sjzx.redis.timeout}")
private int timeout;
@Value("${spring.sjzx.redis.pool.max-idle}")
private int maxIdle = 8;
@Value("${spring.sjzx.redis.pool.min-idle}")
private int minIdle = 0;
@Value("${spring.sjzx.redis.pool.max-active}")
private int maxActive = 8;
@Value("${spring.sjzx.redis.pool.max-wait}")
private Long maxWait = -1L;
private RedisSourceServiceImpl.Pool pool;
private final String REDIS_BEAN_NAME_HEAD = "redis-";
@Autowired
private ConfigurableApplicationContext configurableApplicationContext;
/**
* redis连接存储集合
*/
private volatile Map<String,RedisTemplate<String,Object>> redisTemplateMap = new HashMap<String,RedisTemplate<String, Object>>();
@Autowired
private SourceSysService sourceSysService;
@Override
public RedisTemplate<String,Object> initCreateRedisPool(SourceSys sys) {
List<SourceSys> sourceSyss = new ArrayList<SourceSys>();
if (sys==null){
sourceSyss = sourceSysService.findAll();
for (int i =0 ; i<sourceSyss.size();i++){
createJavaCode(sourceSyss.get(i));
}
return null;
}else {
sourceSyss = sourceSysService.findList(sys.getCode(),sys.getType());
for (SourceSys sourceSys : sourceSyss){
createJavaCode(sourceSys);
}
return redisTemplateMap.get(REDIS_BEAN_NAME_HEAD+(sys.getId()-1));
}
}
@Override
public RedisTemplate<String, Object> getRedisSource(SourceSys sourceSys) {
RedisTemplate<String,Object> redisTemplate = redisTemplateMap.get(REDIS_BEAN_NAME_HEAD+(sourceSys.getId()-1));
if (redisTemplate==null){
redisTemplate = initCreateRedisPool(sourceSys);
}
return redisTemplate;
}
/**************************核心代码*****************************/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.configurableApplicationContext = (ConfigurableApplicationContext) applicationContext;
}
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ContextRefreshedEvent){
try{
initCreateRedisPool(null);
}catch (Exception e){
System.err.println(":"+e.getLocalizedMessage());
System.err.println("创建失败");
}
}
}
/**
* 创建redisTemplate 多例bean
* @param sourceSys
*/
public void createJavaCode(SourceSys sourceSys){
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableApplicationContext.getAutowireCapableBeanFactory();
String db = Integer.valueOf(String.valueOf(sourceSys.getId()))-1+"";
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
JedisShardInfo jedisShardInfo = new JedisShardInfo("http://"+host+":"+port+"/"+db);
jedisShardInfo.setPassword(password);
jedisConnectionFactory.setShardInfo(jedisShardInfo);
jedisConnectionFactory.setUsePool(false);
jedisConnectionFactory.setTimeout(timeout);
pool =new Pool(this.maxIdle,this.minIdle,this.maxActive,this.maxWait);
jedisConnectionFactory.setPoolConfig(pool);
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(RedisTemplate.class);
beanDefinitionBuilder.getBeanDefinition().setAttribute("id",REDIS_BEAN_NAME_HEAD+db);
beanDefinitionBuilder.addPropertyValue("connectionFactory",jedisConnectionFactory);
defaultListableBeanFactory.registerBeanDefinition(REDIS_BEAN_NAME_HEAD+db,beanDefinitionBuilder.getBeanDefinition());
redisTemplateMap.put(REDIS_BEAN_NAME_HEAD+db, (RedisTemplate<String, Object>) configurableApplicationContext.getBean(REDIS_BEAN_NAME_HEAD+db));
}
/*******************************************************/
public static class Pool extends JedisPoolConfig {
private int maxIdle = 8;
private int minIdle = 0;
private int maxActive = 8;
private Long maxWait = -1L;
public Pool() {
}
public Pool(int maxIdle, int minIdle, int maxActive, Long maxWait) {
this.maxIdle = maxIdle;
this.minIdle = minIdle;
this.maxActive = maxActive;
this.maxWait = maxWait;
}
public int getMaxIdle() {
return this.maxIdle;
}
public void setMaxIdle(int maxIdle) {
this.maxIdle = maxIdle;
}
public int getMinIdle() {
return this.minIdle;
}
public void setMinIdle(int minIdle) {
this.minIdle = minIdle;
}
public void setMaxActive(int maxActive) {
this.maxActive = maxActive;
}
@Override
public int getMaxTotal() {
return this.maxActive;
}
@Override
public long getMaxWaitMillis() {
return this.maxWait;
}
public void setMaxWait(Long maxWait) {
this.maxWait = maxWait;
}
}
}