2020import  java .util .ArrayList ;
2121import  java .util .List ;
2222
23+ import  com .lambdaworks .redis .RedisClient ;
24+ import  com .lambdaworks .redis .cluster .RedisClusterClient ;
25+ import  com .lambdaworks .redis .resource .ClientResources ;
26+ import  com .lambdaworks .redis .resource .DefaultClientResources ;
27+ 
2328import  org .apache .commons .pool2 .impl .GenericObjectPool ;
29+ import  org .apache .commons .pool2 .impl .GenericObjectPoolConfig ;
30+ 
2431import  redis .clients .jedis .Jedis ;
2532import  redis .clients .jedis .JedisPoolConfig ;
2633
2936import  org .springframework .boot .autoconfigure .condition .ConditionalOnClass ;
3037import  org .springframework .boot .autoconfigure .condition .ConditionalOnMissingBean ;
3138import  org .springframework .boot .autoconfigure .data .redis .RedisProperties .Cluster ;
39+ import  org .springframework .boot .autoconfigure .data .redis .RedisProperties .Lettuce ;
3240import  org .springframework .boot .autoconfigure .data .redis .RedisProperties .Sentinel ;
3341import  org .springframework .boot .context .properties .EnableConfigurationProperties ;
3442import  org .springframework .context .annotation .Bean ;
3947import  org .springframework .data .redis .connection .RedisSentinelConfiguration ;
4048import  org .springframework .data .redis .connection .jedis .JedisConnection ;
4149import  org .springframework .data .redis .connection .jedis .JedisConnectionFactory ;
50+ import  org .springframework .data .redis .connection .lettuce .DefaultLettucePool ;
51+ import  org .springframework .data .redis .connection .lettuce .LettuceConnectionFactory ;
4252import  org .springframework .data .redis .core .RedisOperations ;
4353import  org .springframework .data .redis .core .RedisTemplate ;
4454import  org .springframework .data .redis .core .StringRedisTemplate ;
4555import  org .springframework .util .Assert ;
4656import  org .springframework .util .StringUtils ;
4757
58+ 
4859/** 
4960 * {@link EnableAutoConfiguration Auto-configuration} for Spring Data's Redis support. 
5061 * 
5566 * @author Phillip Webb 
5667 * @author Eddú Meléndez 
5768 * @author Stephane Nicoll 
69+  * @author Mark Paluch 
5870 */ 
5971@ Configuration 
60- @ ConditionalOnClass ({ JedisConnection . class ,  RedisOperations . class ,  Jedis .class  })
72+ @ ConditionalOnClass ({ RedisOperations .class  })
6173@ EnableConfigurationProperties (RedisProperties .class )
6274public  class  RedisAutoConfiguration  {
6375
6476	/** 
65- 	 * Redis connection configuration. 
77+ 	 * Jedis  Redis connection configuration. 
6678	 */ 
6779	@ Configuration 
68- 	@ ConditionalOnClass (GenericObjectPool .class )
69- 	protected  static  class  RedisConnectionConfiguration  {
80+ 	@ ConditionalOnClass ({  GenericObjectPool .class ,  JedisConnection . class ,  Jedis . class  } )
81+ 	protected  static  class  JedisRedisConnectionConfiguration   extends   RedisBaseConfiguration  {
7082
7183		private  final  RedisProperties  properties ;
7284
73- 		private  final  RedisSentinelConfiguration  sentinelConfiguration ;
74- 
75- 		private  final  RedisClusterConfiguration  clusterConfiguration ;
76- 
77- 		public  RedisConnectionConfiguration (RedisProperties  properties ,
85+ 		public  JedisRedisConnectionConfiguration (RedisProperties  properties ,
7886				ObjectProvider <RedisSentinelConfiguration > sentinelConfigurationProvider ,
7987				ObjectProvider <RedisClusterConfiguration > clusterConfigurationProvider ) {
88+ 			super (properties , sentinelConfigurationProvider , clusterConfigurationProvider );
8089			this .properties  = properties ;
81- 			this .sentinelConfiguration  = sentinelConfigurationProvider .getIfAvailable ();
82- 			this .clusterConfiguration  = clusterConfigurationProvider .getIfAvailable ();
8390		}
8491
8592		@ Bean 
@@ -103,10 +110,174 @@ protected final JedisConnectionFactory applyProperties(
103110			return  factory ;
104111		}
105112
113+ 		private  JedisConnectionFactory  createJedisConnectionFactory () {
114+ 
115+ 			JedisPoolConfig  poolConfig ;
116+ 			if  (this .properties .getJedis () != null  && this .properties .getJedis ().getPool () != null ) {
117+ 				poolConfig  = jedisPoolConfig (this .properties .getJedis ().getPool ());
118+ 			}
119+ 			else  {
120+ 				poolConfig  = new  JedisPoolConfig ();
121+ 			}
122+ 
123+ 			if  (getSentinelConfig () != null ) {
124+ 				return  new  JedisConnectionFactory (getSentinelConfig (), poolConfig );
125+ 			}
126+ 			if  (getClusterConfiguration () != null ) {
127+ 				return  new  JedisConnectionFactory (getClusterConfiguration (), poolConfig );
128+ 			}
129+ 			return  new  JedisConnectionFactory (poolConfig );
130+ 		}
131+ 
132+ 		private  JedisPoolConfig  jedisPoolConfig (RedisProperties .Pool  props ) {
133+ 			JedisPoolConfig  config  = new  JedisPoolConfig ();
134+ 			config .setMaxTotal (props .getMaxActive ());
135+ 			config .setMaxIdle (props .getMaxIdle ());
136+ 			config .setMinIdle (props .getMinIdle ());
137+ 			config .setMaxWaitMillis (props .getMaxWait ());
138+ 			return  config ;
139+ 		}
140+ 
141+ 	}
142+ 
143+ 	/** 
144+ 	 * Lettuce Redis connection configuration. 
145+ 	 */ 
146+ 	@ Configuration 
147+ 	@ ConditionalOnClass ({ GenericObjectPool .class , RedisClient .class , RedisClusterClient .class })
148+ 	protected  static  class  LettuceRedisConnectionConfiguration  extends  RedisBaseConfiguration  {
149+ 
150+ 		protected  final  RedisProperties  properties ;
151+ 
152+ 		public  LettuceRedisConnectionConfiguration (RedisProperties  properties ,
153+ 				ObjectProvider <RedisSentinelConfiguration > sentinelConfigurationProvider ,
154+ 				ObjectProvider <RedisClusterConfiguration > clusterConfigurationProvider ) {
155+ 			super (properties , sentinelConfigurationProvider , clusterConfigurationProvider );
156+ 			this .properties  = properties ;
157+ 		}
158+ 
159+ 		@ Bean (destroyMethod  = "shutdown" )
160+ 		@ ConditionalOnMissingBean (ClientResources .class )
161+ 		public  DefaultClientResources  lettuceClientResources () {
162+ 			return  DefaultClientResources .create ();
163+ 		}
164+ 
165+ 		@ Bean 
166+ 		@ ConditionalOnMissingBean (RedisConnectionFactory .class )
167+ 		public  LettuceConnectionFactory  redisConnectionFactory (ClientResources  clientResources )
168+ 				throws  UnknownHostException  {
169+ 			return  applyProperties (createLettuceConnectionFactory (clientResources ));
170+ 		}
171+ 
172+ 		protected  final  LettuceConnectionFactory  applyProperties (
173+ 				LettuceConnectionFactory  factory ) {
174+ 			factory .setHostName (this .properties .getHost ());
175+ 			factory .setPort (this .properties .getPort ());
176+ 			if  (this .properties .getPassword () != null ) {
177+ 				factory .setPassword (this .properties .getPassword ());
178+ 			}
179+ 			factory .setDatabase (this .properties .getDatabase ());
180+ 			if  (this .properties .getTimeout () > 0 ) {
181+ 				factory .setTimeout (this .properties .getTimeout ());
182+ 			}
183+ 			if  (this .properties .getSsl () != null ) {
184+ 				factory .setUseSsl (this .properties .getSsl ().isEnabled ());
185+ 				factory .setStartTls (this .properties .getSsl ().isStartTls ());
186+ 				factory .setVerifyPeer (this .properties .getSsl ().isVerifyPeer ());
187+ 			}
188+ 			if  (this .properties .getLettuce () != null ) {
189+ 
190+ 				Lettuce  lettuce  = this .properties .getLettuce ();
191+ 				if  (lettuce .getShutdownTimeout () >= 0 ) {
192+ 					factory .setShutdownTimeout (this .properties .getLettuce ().getShutdownTimeout ());
193+ 				}
194+ 			}
195+ 
196+ 			return  factory ;
197+ 		}
198+ 
199+ 		protected  final  DefaultLettucePool  applyProperties (
200+ 				DefaultLettucePool  pool ) {
201+ 			pool .setHostName (this .properties .getHost ());
202+ 			pool .setPort (this .properties .getPort ());
203+ 			if  (this .properties .getPassword () != null ) {
204+ 				pool .setPassword (this .properties .getPassword ());
205+ 			}
206+ 			pool .setDatabase (this .properties .getDatabase ());
207+ 			if  (this .properties .getTimeout () > 0 ) {
208+ 				pool .setTimeout (this .properties .getTimeout ());
209+ 			}
210+ 
211+ 			pool .afterPropertiesSet ();
212+ 
213+ 			return  pool ;
214+ 		}
215+ 
216+ 		private  LettuceConnectionFactory  createLettuceConnectionFactory (ClientResources  clientResources ) {
217+ 
218+ 			if  (getSentinelConfig () != null ) {
219+ 				if  (this .properties .getLettuce () != null  && this .properties .getLettuce ().getPool () != null ) {
220+ 					DefaultLettucePool  lettucePool  = new  DefaultLettucePool (getSentinelConfig ());
221+ 					return  new  LettuceConnectionFactory (applyProperties (applyClientResources (lettucePool , clientResources )));
222+ 				}
223+ 				return  applyClientResources (new  LettuceConnectionFactory (getSentinelConfig ()), clientResources );
224+ 			}
225+ 
226+ 			if  (getClusterConfiguration () != null ) {
227+ 				return  applyClientResources (new  LettuceConnectionFactory (getClusterConfiguration ()), clientResources );
228+ 			}
229+ 
230+ 			if  (this .properties .getLettuce () != null  && this .properties .getLettuce ().getPool () != null ) {
231+ 				GenericObjectPoolConfig  config  = lettucePoolConfig (this .properties .getLettuce ().getPool ());
232+ 				DefaultLettucePool  lettucePool  = new  DefaultLettucePool (this .properties .getHost (), this .properties .getPort (), config );
233+ 				return  new  LettuceConnectionFactory (applyProperties (applyClientResources (lettucePool , clientResources )));
234+ 			}
235+ 
236+ 			return  applyClientResources (new  LettuceConnectionFactory (), clientResources );
237+ 		}
238+ 
239+ 		private  DefaultLettucePool  applyClientResources (DefaultLettucePool  lettucePool , ClientResources  clientResources ) {
240+ 			lettucePool .setClientResources (clientResources );
241+ 			return  lettucePool ;
242+ 		}
243+ 
244+ 		private  LettuceConnectionFactory  applyClientResources (LettuceConnectionFactory  factory , ClientResources  clientResources ) {
245+ 			factory .setClientResources (clientResources );
246+ 			return  factory ;
247+ 		}
248+ 
249+ 		private  GenericObjectPoolConfig  lettucePoolConfig (RedisProperties .Pool  props ) {
250+ 			GenericObjectPoolConfig  config  = new  GenericObjectPoolConfig ();
251+ 			config .setMaxTotal (props .getMaxActive ());
252+ 			config .setMaxIdle (props .getMaxIdle ());
253+ 			config .setMinIdle (props .getMinIdle ());
254+ 			config .setMaxWaitMillis (props .getMaxWait ());
255+ 			return  config ;
256+ 		}
257+ 
258+ 	}
259+ 
260+ 	protected  abstract  static  class  RedisBaseConfiguration  {
261+ 
262+ 		protected  final  RedisProperties  properties ;
263+ 
264+ 		protected  final  RedisSentinelConfiguration  sentinelConfiguration ;
265+ 
266+ 		protected  final  RedisClusterConfiguration  clusterConfiguration ;
267+ 
268+ 		public  RedisBaseConfiguration (RedisProperties  properties ,
269+ 				ObjectProvider <RedisSentinelConfiguration > sentinelConfigurationProvider ,
270+ 				ObjectProvider <RedisClusterConfiguration > clusterConfigurationProvider ) {
271+ 			this .properties  = properties ;
272+ 			this .sentinelConfiguration  = sentinelConfigurationProvider .getIfAvailable ();
273+ 			this .clusterConfiguration  = clusterConfigurationProvider .getIfAvailable ();
274+ 		}
275+ 
106276		protected  final  RedisSentinelConfiguration  getSentinelConfig () {
107277			if  (this .sentinelConfiguration  != null ) {
108278				return  this .sentinelConfiguration ;
109279			}
280+ 
110281			Sentinel  sentinelProperties  = this .properties .getSentinel ();
111282			if  (sentinelProperties  != null ) {
112283				RedisSentinelConfiguration  config  = new  RedisSentinelConfiguration ();
@@ -125,9 +296,11 @@ protected final RedisClusterConfiguration getClusterConfiguration() {
125296			if  (this .clusterConfiguration  != null ) {
126297				return  this .clusterConfiguration ;
127298			}
299+ 
128300			if  (this .properties .getCluster () == null ) {
129301				return  null ;
130302			}
303+ 
131304			Cluster  clusterProperties  = this .properties .getCluster ();
132305			RedisClusterConfiguration  config  = new  RedisClusterConfiguration (
133306					clusterProperties .getNodes ());
@@ -155,29 +328,6 @@ private List<RedisNode> createSentinels(Sentinel sentinel) {
155328			return  nodes ;
156329		}
157330
158- 		private  JedisConnectionFactory  createJedisConnectionFactory () {
159- 			JedisPoolConfig  poolConfig  = this .properties .getPool () != null 
160- 					? jedisPoolConfig () : new  JedisPoolConfig ();
161- 
162- 			if  (getSentinelConfig () != null ) {
163- 				return  new  JedisConnectionFactory (getSentinelConfig (), poolConfig );
164- 			}
165- 			if  (getClusterConfiguration () != null ) {
166- 				return  new  JedisConnectionFactory (getClusterConfiguration (), poolConfig );
167- 			}
168- 			return  new  JedisConnectionFactory (poolConfig );
169- 		}
170- 
171- 		private  JedisPoolConfig  jedisPoolConfig () {
172- 			JedisPoolConfig  config  = new  JedisPoolConfig ();
173- 			RedisProperties .Pool  props  = this .properties .getPool ();
174- 			config .setMaxTotal (props .getMaxActive ());
175- 			config .setMaxIdle (props .getMaxIdle ());
176- 			config .setMinIdle (props .getMinIdle ());
177- 			config .setMaxWaitMillis (props .getMaxWait ());
178- 			return  config ;
179- 		}
180- 
181331	}
182332
183333	/** 
0 commit comments