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}