001/* 002 * Copyright 2002-2015 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.aop.target; 018 019import org.apache.commons.pool.ObjectPool; 020import org.apache.commons.pool.PoolableObjectFactory; 021import org.apache.commons.pool.impl.GenericObjectPool; 022 023import org.springframework.beans.BeansException; 024import org.springframework.core.Constants; 025 026/** 027 * {@link org.springframework.aop.TargetSource} implementation that holds 028 * objects in a configurable Apache Commons Pool. 029 * 030 * <p>By default, an instance of {@code GenericObjectPool} is created. 031 * Subclasses may change the type of {@code ObjectPool} used by 032 * overriding the {@code createObjectPool()} method. 033 * 034 * <p>Provides many configuration properties mirroring those of the Commons Pool 035 * {@code GenericObjectPool} class; these properties are passed to the 036 * {@code GenericObjectPool} during construction. If creating a subclass of this 037 * class to change the {@code ObjectPool} implementation type, pass in the values 038 * of configuration properties that are relevant to your chosen implementation. 039 * 040 * <p>The {@code testOnBorrow}, {@code testOnReturn} and {@code testWhileIdle} 041 * properties are explicitly not mirrored because the implementation of 042 * {@code PoolableObjectFactory} used by this class does not implement 043 * meaningful validation. All exposed Commons Pool properties use the 044 * corresponding Commons Pool defaults. 045 * 046 * <p>Compatible with Apache Commons Pool 1.5.x and 1.6. 047 * Note that this class doesn't declare Commons Pool 1.6's generic type 048 * in order to remain compatible with Commons Pool 1.5.x at runtime. 049 * 050 * @author Rod Johnson 051 * @author Rob Harrop 052 * @author Juergen Hoeller 053 * @see GenericObjectPool 054 * @see #createObjectPool() 055 * @see #setMaxSize 056 * @see #setMaxIdle 057 * @see #setMinIdle 058 * @see #setMaxWait 059 * @see #setTimeBetweenEvictionRunsMillis 060 * @see #setMinEvictableIdleTimeMillis 061 * @deprecated as of Spring 4.2, in favor of {@link CommonsPool2TargetSource} 062 */ 063@SuppressWarnings({"rawtypes", "unchecked", "serial"}) 064@Deprecated 065public class CommonsPoolTargetSource extends AbstractPoolingTargetSource implements PoolableObjectFactory { 066 067 private static final Constants constants = new Constants(GenericObjectPool.class); 068 069 070 private int maxIdle = GenericObjectPool.DEFAULT_MAX_IDLE; 071 072 private int minIdle = GenericObjectPool.DEFAULT_MIN_IDLE; 073 074 private long maxWait = GenericObjectPool.DEFAULT_MAX_WAIT; 075 076 private long timeBetweenEvictionRunsMillis = GenericObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS; 077 078 private long minEvictableIdleTimeMillis = GenericObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS; 079 080 private byte whenExhaustedAction = GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION; 081 082 /** 083 * The Apache Commons {@code ObjectPool} used to pool target objects 084 */ 085 private ObjectPool pool; 086 087 088 /** 089 * Create a CommonsPoolTargetSource with default settings. 090 * Default maximum size of the pool is 8. 091 * @see #setMaxSize 092 * @see GenericObjectPool#setMaxActive 093 */ 094 public CommonsPoolTargetSource() { 095 setMaxSize(GenericObjectPool.DEFAULT_MAX_ACTIVE); 096 } 097 098 /** 099 * Set the maximum number of idle objects in the pool. 100 * Default is 8. 101 * @see GenericObjectPool#setMaxIdle 102 */ 103 public void setMaxIdle(int maxIdle) { 104 this.maxIdle = maxIdle; 105 } 106 107 /** 108 * Return the maximum number of idle objects in the pool. 109 */ 110 public int getMaxIdle() { 111 return this.maxIdle; 112 } 113 114 /** 115 * Set the minimum number of idle objects in the pool. 116 * Default is 0. 117 * @see GenericObjectPool#setMinIdle 118 */ 119 public void setMinIdle(int minIdle) { 120 this.minIdle = minIdle; 121 } 122 123 /** 124 * Return the minimum number of idle objects in the pool. 125 */ 126 public int getMinIdle() { 127 return this.minIdle; 128 } 129 130 /** 131 * Set the maximum waiting time for fetching an object from the pool. 132 * Default is -1, waiting forever. 133 * @see GenericObjectPool#setMaxWait 134 */ 135 public void setMaxWait(long maxWait) { 136 this.maxWait = maxWait; 137 } 138 139 /** 140 * Return the maximum waiting time for fetching an object from the pool. 141 */ 142 public long getMaxWait() { 143 return this.maxWait; 144 } 145 146 /** 147 * Set the time between eviction runs that check idle objects whether 148 * they have been idle for too long or have become invalid. 149 * Default is -1, not performing any eviction. 150 * @see GenericObjectPool#setTimeBetweenEvictionRunsMillis 151 */ 152 public void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) { 153 this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis; 154 } 155 156 /** 157 * Return the time between eviction runs that check idle objects. 158 */ 159 public long getTimeBetweenEvictionRunsMillis() { 160 return this.timeBetweenEvictionRunsMillis; 161 } 162 163 /** 164 * Set the minimum time that an idle object can sit in the pool before 165 * it becomes subject to eviction. Default is 1800000 (30 minutes). 166 * <p>Note that eviction runs need to be performed to take this 167 * setting into effect. 168 * @see #setTimeBetweenEvictionRunsMillis 169 * @see GenericObjectPool#setMinEvictableIdleTimeMillis 170 */ 171 public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) { 172 this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis; 173 } 174 175 /** 176 * Return the minimum time that an idle object can sit in the pool. 177 */ 178 public long getMinEvictableIdleTimeMillis() { 179 return this.minEvictableIdleTimeMillis; 180 } 181 182 /** 183 * Set the action to take when the pool is exhausted. Uses the 184 * constant names defined in Commons Pool's GenericObjectPool class: 185 * "WHEN_EXHAUSTED_BLOCK", "WHEN_EXHAUSTED_FAIL", "WHEN_EXHAUSTED_GROW". 186 * @see #setWhenExhaustedAction(byte) 187 */ 188 public void setWhenExhaustedActionName(String whenExhaustedActionName) { 189 setWhenExhaustedAction(constants.asNumber(whenExhaustedActionName).byteValue()); 190 } 191 192 /** 193 * Set the action to take when the pool is exhausted. Uses the 194 * constant values defined in Commons Pool's GenericObjectPool class. 195 * @see GenericObjectPool#setWhenExhaustedAction(byte) 196 * @see GenericObjectPool#WHEN_EXHAUSTED_BLOCK 197 * @see GenericObjectPool#WHEN_EXHAUSTED_FAIL 198 * @see GenericObjectPool#WHEN_EXHAUSTED_GROW 199 */ 200 public void setWhenExhaustedAction(byte whenExhaustedAction) { 201 this.whenExhaustedAction = whenExhaustedAction; 202 } 203 204 /** 205 * Return the action to take when the pool is exhausted. 206 */ 207 public byte getWhenExhaustedAction() { 208 return whenExhaustedAction; 209 } 210 211 212 /** 213 * Creates and holds an ObjectPool instance. 214 * @see #createObjectPool() 215 */ 216 @Override 217 protected final void createPool() { 218 logger.debug("Creating Commons object pool"); 219 this.pool = createObjectPool(); 220 } 221 222 /** 223 * Subclasses can override this if they want to return a specific Commons pool. 224 * They should apply any configuration properties to the pool here. 225 * <p>Default is a GenericObjectPool instance with the given pool size. 226 * @return an empty Commons {@code ObjectPool}. 227 * @see org.apache.commons.pool.impl.GenericObjectPool 228 * @see #setMaxSize 229 */ 230 protected ObjectPool createObjectPool() { 231 GenericObjectPool gop = new GenericObjectPool(this); 232 gop.setMaxActive(getMaxSize()); 233 gop.setMaxIdle(getMaxIdle()); 234 gop.setMinIdle(getMinIdle()); 235 gop.setMaxWait(getMaxWait()); 236 gop.setTimeBetweenEvictionRunsMillis(getTimeBetweenEvictionRunsMillis()); 237 gop.setMinEvictableIdleTimeMillis(getMinEvictableIdleTimeMillis()); 238 gop.setWhenExhaustedAction(getWhenExhaustedAction()); 239 return gop; 240 } 241 242 243 /** 244 * Borrow an object from the {@code ObjectPool}. 245 */ 246 @Override 247 public Object getTarget() throws Exception { 248 return this.pool.borrowObject(); 249 } 250 251 /** 252 * Returns the specified object to the underlying {@code ObjectPool}. 253 */ 254 @Override 255 public void releaseTarget(Object target) throws Exception { 256 this.pool.returnObject(target); 257 } 258 259 @Override 260 public int getActiveCount() throws UnsupportedOperationException { 261 return this.pool.getNumActive(); 262 } 263 264 @Override 265 public int getIdleCount() throws UnsupportedOperationException { 266 return this.pool.getNumIdle(); 267 } 268 269 270 /** 271 * Closes the underlying {@code ObjectPool} when destroying this object. 272 */ 273 @Override 274 public void destroy() throws Exception { 275 logger.debug("Closing Commons ObjectPool"); 276 this.pool.close(); 277 } 278 279 280 //---------------------------------------------------------------------------- 281 // Implementation of org.apache.commons.pool.PoolableObjectFactory interface 282 //---------------------------------------------------------------------------- 283 284 @Override 285 public Object makeObject() throws BeansException { 286 return newPrototypeInstance(); 287 } 288 289 @Override 290 public void destroyObject(Object obj) throws Exception { 291 destroyPrototypeInstance(obj); 292 } 293 294 @Override 295 public boolean validateObject(Object obj) { 296 return true; 297 } 298 299 @Override 300 public void activateObject(Object obj) { 301 } 302 303 @Override 304 public void passivateObject(Object obj) { 305 } 306 307}