org.springframework.aop.target.CommonsPool2TargetSource.java Source code

Java tutorial

Introduction

Here is the source code for org.springframework.aop.target.CommonsPool2TargetSource.java

Source

/*
 * Copyright 2002-2017 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.aop.target;

import org.apache.commons.pool2.ObjectPool;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

import org.springframework.lang.Nullable;
import org.springframework.util.Assert;

/**
 * {@link org.springframework.aop.TargetSource} implementation that holds
 * objects in a configurable Apache Commons2 Pool.
 *
 * <p>By default, an instance of {@code GenericObjectPool} is created.
 * Subclasses may change the type of {@code ObjectPool} used by
 * overriding the {@code createObjectPool()} method.
 *
 * <p>Provides many configuration properties mirroring those of the Commons Pool
 * {@code GenericObjectPool} class; these properties are passed to the
 * {@code GenericObjectPool} during construction. If creating a subclass of this
 * class to change the {@code ObjectPool} implementation type, pass in the values
 * of configuration properties that are relevant to your chosen implementation.
 *
 * <p>The {@code testOnBorrow}, {@code testOnReturn} and {@code testWhileIdle}
 * properties are explicitly not mirrored because the implementation of
 * {@code PoolableObjectFactory} used by this class does not implement
 * meaningful validation. All exposed Commons Pool properties use the
 * corresponding Commons Pool defaults.
 *
 * <p>Compatible with Apache Commons Pool 2.4, as of Spring 4.2.
 *
 * @author Rod Johnson
 * @author Rob Harrop
 * @author Juergen Hoeller
 * @author Stephane Nicoll
 * @author Kazuki Shimizu
 * @since 4.2
 * @see GenericObjectPool
 * @see #createObjectPool()
 * @see #setMaxSize
 * @see #setMaxIdle
 * @see #setMinIdle
 * @see #setMaxWait
 * @see #setTimeBetweenEvictionRunsMillis
 * @see #setMinEvictableIdleTimeMillis
 */
@SuppressWarnings({ "rawtypes", "unchecked", "serial" })
public class CommonsPool2TargetSource extends AbstractPoolingTargetSource implements PooledObjectFactory<Object> {

    private int maxIdle = GenericObjectPoolConfig.DEFAULT_MAX_IDLE;

    private int minIdle = GenericObjectPoolConfig.DEFAULT_MIN_IDLE;

    private long maxWait = GenericObjectPoolConfig.DEFAULT_MAX_WAIT_MILLIS;

    private long timeBetweenEvictionRunsMillis = GenericObjectPoolConfig.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;

    private long minEvictableIdleTimeMillis = GenericObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;

    private boolean blockWhenExhausted = GenericObjectPoolConfig.DEFAULT_BLOCK_WHEN_EXHAUSTED;

    /**
     * The Apache Commons {@code ObjectPool} used to pool target objects
     */
    @Nullable
    private ObjectPool pool;

    /**
     * Create a CommonsPoolTargetSource with default settings.
     * Default maximum size of the pool is 8.
     * @see #setMaxSize
     * @see GenericObjectPoolConfig#setMaxTotal
     */
    public CommonsPool2TargetSource() {
        setMaxSize(GenericObjectPoolConfig.DEFAULT_MAX_TOTAL);
    }

    /**
     * Set the maximum number of idle objects in the pool.
     * Default is 8.
     * @see GenericObjectPool#setMaxIdle
     */
    public void setMaxIdle(int maxIdle) {
        this.maxIdle = maxIdle;
    }

    /**
     * Return the maximum number of idle objects in the pool.
     */
    public int getMaxIdle() {
        return this.maxIdle;
    }

    /**
     * Set the minimum number of idle objects in the pool.
     * Default is 0.
     * @see GenericObjectPool#setMinIdle
     */
    public void setMinIdle(int minIdle) {
        this.minIdle = minIdle;
    }

    /**
     * Return the minimum number of idle objects in the pool.
     */
    public int getMinIdle() {
        return this.minIdle;
    }

    /**
     * Set the maximum waiting time for fetching an object from the pool.
     * Default is -1, waiting forever.
     * @see GenericObjectPool#setMaxWaitMillis
     */
    public void setMaxWait(long maxWait) {
        this.maxWait = maxWait;
    }

    /**
     * Return the maximum waiting time for fetching an object from the pool.
     */
    public long getMaxWait() {
        return this.maxWait;
    }

    /**
     * Set the time between eviction runs that check idle objects whether
     * they have been idle for too long or have become invalid.
     * Default is -1, not performing any eviction.
     * @see GenericObjectPool#setTimeBetweenEvictionRunsMillis
     */
    public void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
        this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
    }

    /**
     * Return the time between eviction runs that check idle objects.
     */
    public long getTimeBetweenEvictionRunsMillis() {
        return this.timeBetweenEvictionRunsMillis;
    }

    /**
     * Set the minimum time that an idle object can sit in the pool before
     * it becomes subject to eviction. Default is 1800000 (30 minutes).
     * <p>Note that eviction runs need to be performed to take this
     * setting into effect.
     * @see #setTimeBetweenEvictionRunsMillis
     * @see GenericObjectPool#setMinEvictableIdleTimeMillis
     */
    public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
        this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
    }

    /**
     * Return the minimum time that an idle object can sit in the pool.
     */
    public long getMinEvictableIdleTimeMillis() {
        return this.minEvictableIdleTimeMillis;
    }

    /**
     * Set whether the call should bock when the pool is exhausted.
     */
    public void setBlockWhenExhausted(boolean blockWhenExhausted) {
        this.blockWhenExhausted = blockWhenExhausted;
    }

    /**
     * Specify if the call should block when the pool is exhausted.
     */
    public boolean isBlockWhenExhausted() {
        return this.blockWhenExhausted;
    }

    /**
     * Creates and holds an ObjectPool instance.
     * @see #createObjectPool()
     */
    @Override
    protected final void createPool() {
        logger.debug("Creating Commons object pool");
        this.pool = createObjectPool();
    }

    /**
     * Subclasses can override this if they want to return a specific Commons pool.
     * They should apply any configuration properties to the pool here.
     * <p>Default is a GenericObjectPool instance with the given pool size.
     * @return an empty Commons {@code ObjectPool}.
     * @see GenericObjectPool
     * @see #setMaxSize
     */
    protected ObjectPool createObjectPool() {
        GenericObjectPoolConfig config = new GenericObjectPoolConfig();
        config.setMaxTotal(getMaxSize());
        config.setMaxIdle(getMaxIdle());
        config.setMinIdle(getMinIdle());
        config.setMaxWaitMillis(getMaxWait());
        config.setTimeBetweenEvictionRunsMillis(getTimeBetweenEvictionRunsMillis());
        config.setMinEvictableIdleTimeMillis(getMinEvictableIdleTimeMillis());
        config.setBlockWhenExhausted(isBlockWhenExhausted());
        return new GenericObjectPool(this, config);
    }

    /**
     * Borrows an object from the {@code ObjectPool}.
     */
    @Override
    public Object getTarget() throws Exception {
        Assert.state(this.pool != null, "No Commons ObjectPool available");
        return this.pool.borrowObject();
    }

    /**
     * Returns the specified object to the underlying {@code ObjectPool}.
     */
    @Override
    public void releaseTarget(Object target) throws Exception {
        if (this.pool != null) {
            this.pool.returnObject(target);
        }
    }

    @Override
    public int getActiveCount() throws UnsupportedOperationException {
        return (this.pool != null ? this.pool.getNumActive() : 0);
    }

    @Override
    public int getIdleCount() throws UnsupportedOperationException {
        return (this.pool != null ? this.pool.getNumIdle() : 0);
    }

    /**
     * Closes the underlying {@code ObjectPool} when destroying this object.
     */
    @Override
    public void destroy() throws Exception {
        if (this.pool != null) {
            logger.debug("Closing Commons ObjectPool");
            this.pool.close();
        }
    }

    //----------------------------------------------------------------------------
    // Implementation of org.apache.commons.pool2.PooledObjectFactory interface
    //----------------------------------------------------------------------------

    @Override
    public PooledObject<Object> makeObject() throws Exception {
        return new DefaultPooledObject<>(newPrototypeInstance());
    }

    @Override
    public void destroyObject(PooledObject<Object> p) throws Exception {
        destroyPrototypeInstance(p.getObject());
    }

    @Override
    public boolean validateObject(PooledObject<Object> p) {
        return true;
    }

    @Override
    public void activateObject(PooledObject<Object> p) throws Exception {
    }

    @Override
    public void passivateObject(PooledObject<Object> p) throws Exception {
    }

}