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.springframework.aop.support.DefaultIntroductionAdvisor;
020import org.springframework.aop.support.DelegatingIntroductionInterceptor;
021import org.springframework.beans.BeansException;
022import org.springframework.beans.factory.BeanFactory;
023import org.springframework.beans.factory.BeanInitializationException;
024import org.springframework.beans.factory.DisposableBean;
025
026/**
027 * Abstract base class for pooling {@link org.springframework.aop.TargetSource}
028 * implementations which maintain a pool of target instances, acquiring and
029 * releasing a target object from the pool for each method invocation.
030 * This abstract base class is independent of concrete pooling technology;
031 * see the subclass {@link CommonsPool2TargetSource} for a concrete example.
032 *
033 * <p>Subclasses must implement the {@link #getTarget} and
034 * {@link #releaseTarget} methods based on their chosen object pool.
035 * The {@link #newPrototypeInstance()} method inherited from
036 * {@link AbstractPrototypeBasedTargetSource} can be used to create objects
037 * in order to put them into the pool.
038 *
039 * <p>Subclasses must also implement some of the monitoring methods from the
040 * {@link PoolingConfig} interface. The {@link #getPoolingConfigMixin()} method
041 * makes these stats available on proxied objects through an IntroductionAdvisor.
042 *
043 * <p>This class implements the {@link org.springframework.beans.factory.DisposableBean}
044 * interface in order to force subclasses to implement a {@link #destroy()}
045 * method, closing down their object pool.
046 *
047 * @author Rod Johnson
048 * @author Juergen Hoeller
049 * @see #getTarget
050 * @see #releaseTarget
051 * @see #destroy
052 */
053@SuppressWarnings("serial")
054public abstract class AbstractPoolingTargetSource extends AbstractPrototypeBasedTargetSource
055                implements PoolingConfig, DisposableBean {
056
057        /** The maximum size of the pool */
058        private int maxSize = -1;
059
060
061        /**
062         * Set the maximum size of the pool.
063         * Default is -1, indicating no size limit.
064         */
065        public void setMaxSize(int maxSize) {
066                this.maxSize = maxSize;
067        }
068
069        /**
070         * Return the maximum size of the pool.
071         */
072        @Override
073        public int getMaxSize() {
074                return this.maxSize;
075        }
076
077
078        @Override
079        public final void setBeanFactory(BeanFactory beanFactory) throws BeansException {
080                super.setBeanFactory(beanFactory);
081                try {
082                        createPool();
083                }
084                catch (Throwable ex) {
085                        throw new BeanInitializationException("Could not create instance pool for TargetSource", ex);
086                }
087        }
088
089
090        /**
091         * Create the pool.
092         * @throws Exception to avoid placing constraints on pooling APIs
093         */
094        protected abstract void createPool() throws Exception;
095
096        /**
097         * Acquire an object from the pool.
098         * @return an object from the pool
099         * @throws Exception we may need to deal with checked exceptions from pool
100         * APIs, so we're forgiving with our exception signature
101         */
102        @Override
103        public abstract Object getTarget() throws Exception;
104
105        /**
106         * Return the given object to the pool.
107         * @param target object that must have been acquired from the pool
108         * via a call to {@code getTarget()}
109         * @throws Exception to allow pooling APIs to throw exception
110         * @see #getTarget
111         */
112        @Override
113        public abstract void releaseTarget(Object target) throws Exception;
114
115
116        /**
117         * Return an IntroductionAdvisor that providing a mixin
118         * exposing statistics about the pool maintained by this object.
119         */
120        public DefaultIntroductionAdvisor getPoolingConfigMixin() {
121                DelegatingIntroductionInterceptor dii = new DelegatingIntroductionInterceptor(this);
122                return new DefaultIntroductionAdvisor(dii, PoolingConfig.class);
123        }
124
125}