Add Commons Pool 2 support
Deprecated CommonsPoolTargetSource (supporting commons pool 1.5+) in favor of CommonsPool2TargetSource with a similar contract. Commons Pool 2.x uses object equality while Commons Pool 1.x used identity equality. This clearly means that Commons Pool 2 behaves differently if several instances having the same identity according to their `Object#equals(Object)` method are managed in the same pool. To provide a smooth upgrade, a backward-compatible pool is created by default; use `setUseObjectEquality(boolean)` if you need the standard Commons Pool 2.x behavior. Issue: SPR-12532
This commit is contained in:
@@ -405,6 +405,7 @@ project("spring-aop") {
|
||||
compile("aopalliance:aopalliance:1.0")
|
||||
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
|
||||
optional("commons-pool:commons-pool:1.6")
|
||||
optional("org.apache.commons:commons-pool2:2.2")
|
||||
optional("com.jamonapi:jamon:2.79")
|
||||
}
|
||||
}
|
||||
@@ -463,6 +464,7 @@ project("spring-context") {
|
||||
optional("org.jruby:jruby:1.7.17")
|
||||
testCompile("javax.inject:javax.inject-tck:1")
|
||||
testCompile("commons-dbcp:commons-dbcp:1.4")
|
||||
testCompile("org.apache.commons:commons-pool2:2.2")
|
||||
testCompile("org.slf4j:slf4j-api:${slf4jVersion}")
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -66,7 +66,7 @@ public abstract class AbstractSingletonProxyFactoryBean extends ProxyConfig
|
||||
* @see org.springframework.aop.target.SingletonTargetSource
|
||||
* @see org.springframework.aop.target.LazyInitTargetSource
|
||||
* @see org.springframework.aop.target.PrototypeTargetSource
|
||||
* @see org.springframework.aop.target.CommonsPoolTargetSource
|
||||
* @see org.springframework.aop.target.CommonsPool2TargetSource
|
||||
*/
|
||||
public void setTarget(Object target) {
|
||||
this.target = target;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -17,19 +17,20 @@
|
||||
package org.springframework.aop.framework.autoproxy.target;
|
||||
|
||||
import org.springframework.aop.target.AbstractBeanFactoryBasedTargetSource;
|
||||
import org.springframework.aop.target.CommonsPoolTargetSource;
|
||||
import org.springframework.aop.target.CommonsPool2TargetSource;
|
||||
import org.springframework.aop.target.PrototypeTargetSource;
|
||||
import org.springframework.aop.target.ThreadLocalTargetSource;
|
||||
|
||||
/**
|
||||
* Convenient TargetSourceCreator using bean name prefixes to create one of three
|
||||
* well-known TargetSource types:
|
||||
* <li>: CommonsPoolTargetSource
|
||||
* <li>: CommonsPool2TargetSource
|
||||
* <li>% ThreadLocalTargetSource
|
||||
* <li>! PrototypeTargetSource
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @see org.springframework.aop.target.CommonsPoolTargetSource
|
||||
* @author Stephane Nicoll
|
||||
* @see org.springframework.aop.target.CommonsPool2TargetSource
|
||||
* @see org.springframework.aop.target.ThreadLocalTargetSource
|
||||
* @see org.springframework.aop.target.PrototypeTargetSource
|
||||
*/
|
||||
@@ -44,7 +45,7 @@ public class QuickTargetSourceCreator extends AbstractBeanFactoryBasedTargetSour
|
||||
Class<?> beanClass, String beanName) {
|
||||
|
||||
if (beanName.startsWith(PREFIX_COMMONS_POOL)) {
|
||||
CommonsPoolTargetSource cpts = new CommonsPoolTargetSource();
|
||||
CommonsPool2TargetSource cpts = new CommonsPool2TargetSource();
|
||||
cpts.setMaxSize(25);
|
||||
return cpts;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -45,7 +45,7 @@ import org.springframework.util.ObjectUtils;
|
||||
* @see LazyInitTargetSource
|
||||
* @see PrototypeTargetSource
|
||||
* @see ThreadLocalTargetSource
|
||||
* @see CommonsPoolTargetSource
|
||||
* @see CommonsPool2TargetSource
|
||||
*/
|
||||
public abstract class AbstractBeanFactoryBasedTargetSource implements TargetSource, BeanFactoryAware, Serializable {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -28,7 +28,7 @@ import org.springframework.beans.factory.DisposableBean;
|
||||
* implementations which maintain a pool of target instances, acquiring and
|
||||
* releasing a target object from the pool for each method invocation.
|
||||
* This abstract base class is independent of concrete pooling technology;
|
||||
* see the subclass {@link CommonsPoolTargetSource} for a concrete example.
|
||||
* see the subclass {@link CommonsPool2TargetSource} for a concrete example.
|
||||
*
|
||||
* <p>Subclasses must implement the {@link #getTarget} and
|
||||
* {@link #releaseTarget} methods based on their chosen object pool.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -41,7 +41,7 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
* @see org.springframework.beans.factory.BeanFactory#getBean
|
||||
* @see PrototypeTargetSource
|
||||
* @see ThreadLocalTargetSource
|
||||
* @see CommonsPoolTargetSource
|
||||
* @see CommonsPool2TargetSource
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public abstract class AbstractPrototypeBasedTargetSource extends AbstractBeanFactoryBasedTargetSource {
|
||||
|
||||
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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;
|
||||
|
||||
/**
|
||||
* {@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>Commons Pool 2.x uses object equality while Commons Pool 1.x used identity
|
||||
* equality. This clearly means that Commons Pool 2 behaves differently if several
|
||||
* instances having the same identity according to their {@link Object#equals(Object)}
|
||||
* method are managed in the same pool. To provide a smooth upgrade, a
|
||||
* backward-compatible pool is created by default; use {@link #setUseObjectEquality(boolean)}
|
||||
* if you need the standard Commons Pool 2.x behavior.
|
||||
*
|
||||
* <p>Compatible with Apache Commons Pool 2.2
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @author Stephane Nicoll
|
||||
* @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_TOTAL;
|
||||
|
||||
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;
|
||||
|
||||
private boolean useObjectEquality;
|
||||
|
||||
/**
|
||||
* The Jakarta Commons {@code ObjectPool} used to pool target objects
|
||||
*/
|
||||
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#setMaxTotal
|
||||
*/
|
||||
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 blockWhenExhausted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if the pool should use object equality. Commons Pool 1.x has no specific requirement in
|
||||
* that regard and allows two distinct instances being equal to be put in the same pool. However,
|
||||
* this behavior has changed with commons pool 2. To preserve backward compatibility, the pool
|
||||
* is configured to use reference equality ({@code false}.
|
||||
*/
|
||||
public void setUseObjectEquality(boolean useObjectEquality) {
|
||||
this.useObjectEquality = useObjectEquality;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify if the pool should use object equality. Return {@code false} if it should use
|
||||
* reference equality (as it was the case for Commons Pool 1.x)
|
||||
*/
|
||||
public boolean isUseObjectEquality() {
|
||||
return useObjectEquality;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Borrow an object from the {@code ObjectPool}.
|
||||
*/
|
||||
@Override
|
||||
public Object getTarget() throws Exception {
|
||||
Object o = this.pool.borrowObject();
|
||||
return (isUseObjectEquality() ? o : ((IdentityWrapper)o).target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the specified object to the underlying {@code ObjectPool}.
|
||||
*/
|
||||
@Override
|
||||
public void releaseTarget(Object target) throws Exception {
|
||||
Object value = (isUseObjectEquality() ? target : new IdentityWrapper(target));
|
||||
this.pool.returnObject(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getActiveCount() throws UnsupportedOperationException {
|
||||
return this.pool.getNumActive();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIdleCount() throws UnsupportedOperationException {
|
||||
return this.pool.getNumIdle();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Closes the underlying {@code ObjectPool} when destroying this object.
|
||||
*/
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
logger.debug("Closing Commons ObjectPool");
|
||||
this.pool.close();
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Implementation of org.apache.commons.pool2.PooledObjectFactory interface
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public PooledObject<Object> makeObject() throws Exception {
|
||||
Object target = newPrototypeInstance();
|
||||
Object poolValue = (isUseObjectEquality() ? target : new IdentityWrapper(target));
|
||||
return new DefaultPooledObject<Object>(poolValue);
|
||||
}
|
||||
|
||||
@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 {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Wraps the target type in the pool to restore the behavior of commons-pool 1.x.
|
||||
*/
|
||||
private static class IdentityWrapper {
|
||||
private final Object target;
|
||||
|
||||
public IdentityWrapper(Object target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return System.identityHashCode(this.target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
IdentityWrapper that = (IdentityWrapper) o;
|
||||
|
||||
return !(target != null ? !(target == that.target) : that.target != null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -58,8 +58,10 @@ import org.springframework.core.Constants;
|
||||
* @see #setMaxWait
|
||||
* @see #setTimeBetweenEvictionRunsMillis
|
||||
* @see #setMinEvictableIdleTimeMillis
|
||||
* @deprecated as of Spring 4.2, in favor of {@link CommonsPool2TargetSource}
|
||||
*/
|
||||
@SuppressWarnings({"rawtypes", "unchecked", "serial"})
|
||||
@Deprecated
|
||||
public class CommonsPoolTargetSource extends AbstractPoolingTargetSource implements PoolableObjectFactory {
|
||||
|
||||
private static final Constants constants = new Constants(GenericObjectPool.class);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -25,7 +25,7 @@ import org.springframework.aop.framework.Advised;
|
||||
import org.springframework.aop.framework.autoproxy.target.AbstractBeanFactoryBasedTargetSourceCreator;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.aop.target.AbstractBeanFactoryBasedTargetSource;
|
||||
import org.springframework.aop.target.CommonsPoolTargetSource;
|
||||
import org.springframework.aop.target.CommonsPool2TargetSource;
|
||||
import org.springframework.aop.target.LazyInitTargetSource;
|
||||
import org.springframework.aop.target.PrototypeTargetSource;
|
||||
import org.springframework.aop.target.ThreadLocalTargetSource;
|
||||
@@ -154,7 +154,7 @@ public final class AdvisorAutoProxyCreatorTests {
|
||||
test = (ITestBean) bf.getBean(":test");
|
||||
assertTrue(AopUtils.isAopProxy(test));
|
||||
Advised advised = (Advised) test;
|
||||
assertTrue(advised.getTargetSource() instanceof CommonsPoolTargetSource);
|
||||
assertTrue(advised.getTargetSource() instanceof CommonsPool2TargetSource);
|
||||
assertEquals("Rod", test.getName());
|
||||
// Check that references survived pooling
|
||||
assertEquals("Kerry", test.getSpouse().getName());
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<property name="count"><value>10</value></property>
|
||||
</bean>
|
||||
|
||||
<bean id="poolTargetSource" class="org.springframework.aop.target.CommonsPoolTargetSource">
|
||||
<bean id="poolTargetSource" class="org.springframework.aop.target.CommonsPool2TargetSource">
|
||||
<property name="targetBeanName"><value>prototypeTest</value></property>
|
||||
<property name="maxSize"><value>25</value></property>
|
||||
</bean>
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
<bean id="prototypePerson" class="org.springframework.tests.sample.beans.SerializablePerson" scope="prototype"/>
|
||||
|
||||
<bean id="personPoolTargetSource" class="org.springframework.aop.target.CommonsPoolTargetSource">
|
||||
<bean id="personPoolTargetSource" class="org.springframework.aop.target.CommonsPool2TargetSource">
|
||||
<property name="targetBeanName"><value>prototypePerson</value></property>
|
||||
<property name="maxSize"><value>10</value></property>
|
||||
</bean>
|
||||
@@ -57,7 +57,7 @@
|
||||
|
||||
<bean id="maxSizePooledPerson" class="org.springframework.aop.framework.ProxyFactoryBean">
|
||||
<property name="targetSource">
|
||||
<bean class="org.springframework.aop.target.CommonsPoolTargetSource">
|
||||
<bean class="org.springframework.aop.target.CommonsPool2TargetSource">
|
||||
<property name="targetBeanName" value="prototypePerson"/>
|
||||
<property name="maxSize" value="10"/>
|
||||
<property name="maxWait" value="1"/>
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -18,10 +18,11 @@ package org.springframework.aop.target;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import org.apache.commons.pool.impl.GenericObjectPool;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import org.springframework.aop.framework.Advised;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
@@ -43,8 +44,12 @@ import static org.junit.Assert.*;
|
||||
* @author Rod Johnson
|
||||
* @author Rob Harrop
|
||||
* @author Chris Beams
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class CommonsPoolTargetSourceTests {
|
||||
public class CommonsPool2TargetSourceTests {
|
||||
|
||||
@Rule
|
||||
public final ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
/**
|
||||
* Initial count value set in bean factory XML
|
||||
@@ -109,7 +114,7 @@ public class CommonsPoolTargetSourceTests {
|
||||
|
||||
@Test
|
||||
public void testTargetSourceSerializableWithoutConfigMixin() throws Exception {
|
||||
CommonsPoolTargetSource cpts = (CommonsPoolTargetSource) beanFactory.getBean("personPoolTargetSource");
|
||||
CommonsPool2TargetSource cpts = (CommonsPool2TargetSource) beanFactory.getBean("personPoolTargetSource");
|
||||
|
||||
SingletonTargetSource serialized = (SingletonTargetSource) SerializationTestUtils.serializeAndDeserialize(cpts);
|
||||
assertTrue(serialized.getTarget() instanceof Person);
|
||||
@@ -121,7 +126,7 @@ public class CommonsPoolTargetSourceTests {
|
||||
Person pooled = (Person) beanFactory.getBean("pooledPerson");
|
||||
|
||||
//System.out.println(((Advised) pooled).toProxyConfigString());
|
||||
assertTrue(((Advised) pooled).getTargetSource() instanceof CommonsPoolTargetSource);
|
||||
assertTrue(((Advised) pooled).getTargetSource() instanceof CommonsPool2TargetSource);
|
||||
|
||||
//((Advised) pooled).setTargetSource(new SingletonTargetSource(new SerializablePerson()));
|
||||
Person serialized = (Person) SerializationTestUtils.serializeAndDeserialize(pooled);
|
||||
@@ -134,7 +139,7 @@ public class CommonsPoolTargetSourceTests {
|
||||
public void testHitMaxSize() throws Exception {
|
||||
int maxSize = 10;
|
||||
|
||||
CommonsPoolTargetSource targetSource = new CommonsPoolTargetSource();
|
||||
CommonsPool2TargetSource targetSource = new CommonsPool2TargetSource();
|
||||
targetSource.setMaxSize(maxSize);
|
||||
targetSource.setMaxWait(1);
|
||||
prepareTargetSource(targetSource);
|
||||
@@ -169,7 +174,7 @@ public class CommonsPoolTargetSourceTests {
|
||||
@Test
|
||||
public void testHitMaxSizeLoadedFromContext() throws Exception {
|
||||
Advised person = (Advised) beanFactory.getBean("maxSizePooledPerson");
|
||||
CommonsPoolTargetSource targetSource = (CommonsPoolTargetSource) person.getTargetSource();
|
||||
CommonsPool2TargetSource targetSource = (CommonsPool2TargetSource) person.getTargetSource();
|
||||
|
||||
int maxSize = targetSource.getMaxSize();
|
||||
Object[] pooledInstances = new Object[maxSize];
|
||||
@@ -195,18 +200,54 @@ public class CommonsPoolTargetSourceTests {
|
||||
|
||||
// release all objects
|
||||
for (int i = 0; i < pooledInstances.length; i++) {
|
||||
System.out.println(i);
|
||||
targetSource.releaseTarget(pooledInstances[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetWhenExhaustedAction() {
|
||||
CommonsPoolTargetSource targetSource = new CommonsPoolTargetSource();
|
||||
targetSource.setWhenExhaustedActionName("WHEN_EXHAUSTED_BLOCK");
|
||||
assertEquals(GenericObjectPool.WHEN_EXHAUSTED_BLOCK, targetSource.getWhenExhaustedAction());
|
||||
CommonsPool2TargetSource targetSource = new CommonsPool2TargetSource();
|
||||
targetSource.setBlockWhenExhausted(true);
|
||||
assertEquals(true, targetSource.isBlockWhenExhausted());
|
||||
}
|
||||
|
||||
private void prepareTargetSource(CommonsPoolTargetSource targetSource) {
|
||||
@Test
|
||||
public void referenceIdentityByDefault() throws Exception {
|
||||
CommonsPool2TargetSource targetSource = new CommonsPool2TargetSource();
|
||||
targetSource.setMaxWait(1);
|
||||
prepareTargetSource(targetSource);
|
||||
|
||||
Object first = targetSource.getTarget();
|
||||
Object second = targetSource.getTarget();
|
||||
assertTrue(first instanceof SerializablePerson);
|
||||
assertTrue(second instanceof SerializablePerson);
|
||||
assertEquals(first, second);
|
||||
|
||||
targetSource.releaseTarget(first);
|
||||
targetSource.releaseTarget(second);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void objectIdentityReleaseWithSeveralEqualInstances() throws Exception{
|
||||
CommonsPool2TargetSource targetSource = new CommonsPool2TargetSource();
|
||||
targetSource.setUseObjectEquality(true);
|
||||
targetSource.setMaxWait(1);
|
||||
prepareTargetSource(targetSource);
|
||||
|
||||
Object first = targetSource.getTarget();
|
||||
Object second = targetSource.getTarget();
|
||||
assertTrue(first instanceof SerializablePerson);
|
||||
assertTrue(second instanceof SerializablePerson);
|
||||
assertEquals(first, second);
|
||||
|
||||
targetSource.releaseTarget(first);
|
||||
thrown.expect(IllegalStateException.class); // Only one object in pool
|
||||
targetSource.releaseTarget(second);
|
||||
|
||||
}
|
||||
|
||||
private void prepareTargetSource(CommonsPool2TargetSource targetSource) {
|
||||
String beanName = "target";
|
||||
|
||||
StaticApplicationContext applicationContext = new StaticApplicationContext();
|
||||
@@ -2049,12 +2049,17 @@ A crucial difference between Spring pooling and SLSB pooling is that Spring pool
|
||||
be applied to any POJO. As with Spring in general, this service can be applied in a
|
||||
non-invasive way.
|
||||
|
||||
Spring provides out-of-the-box support for Jakarta Commons Pool 1.3, which provides a
|
||||
Spring provides out-of-the-box support for Commons Pool 2.2, which provides a
|
||||
fairly efficient pooling implementation. You'll need the commons-pool Jar on your
|
||||
application's classpath to use this feature. It's also possible to subclass
|
||||
`org.springframework.aop.target.AbstractPoolingTargetSource` to support any other
|
||||
pooling API.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
Commons Pool 1.5+ is also supported but deprecated as of Spring Framework 4.2.
|
||||
====
|
||||
|
||||
Sample configuration is shown below:
|
||||
|
||||
[source,xml,indent=0]
|
||||
@@ -2064,7 +2069,7 @@ Sample configuration is shown below:
|
||||
... properties omitted
|
||||
</bean>
|
||||
|
||||
<bean id="poolTargetSource" class="org.springframework.aop.target.CommonsPoolTargetSource">
|
||||
<bean id="poolTargetSource" class="org.springframework.aop.target.CommonsPool2TargetSource">
|
||||
<property name="targetBeanName" value="businessObjectTarget"/>
|
||||
<property name="maxSize" value="25"/>
|
||||
</bean>
|
||||
|
||||
@@ -18305,12 +18305,18 @@ A crucial difference between Spring pooling and SLSB pooling is that Spring pool
|
||||
be applied to any POJO. As with Spring in general, this service can be applied in a
|
||||
non-invasive way.
|
||||
|
||||
Spring provides out-of-the-box support for Jakarta Commons Pool 1.3, which provides a
|
||||
Spring provides out-of-the-box support for Commons Pool 2.2, which provides a
|
||||
fairly efficient pooling implementation. You'll need the commons-pool Jar on your
|
||||
application's classpath to use this feature. It's also possible to subclass
|
||||
`org.springframework.aop.target.AbstractPoolingTargetSource` to support any other
|
||||
pooling API.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
Commons Pool 1.5+ is also supported but deprecated as of Spring Framework 4.2.
|
||||
====
|
||||
|
||||
|
||||
Sample configuration is shown below:
|
||||
|
||||
[source,xml,indent=0]
|
||||
@@ -18321,7 +18327,7 @@ Sample configuration is shown below:
|
||||
... properties omitted
|
||||
</bean>
|
||||
|
||||
<bean id="poolTargetSource" class="org.springframework.aop.target.CommonsPoolTargetSource">
|
||||
<bean id="poolTargetSource" class="org.springframework.aop.target.CommonsPool2TargetSource">
|
||||
<property name="targetBeanName" value="businessObjectTarget"/>
|
||||
<property name="maxSize" value="25"/>
|
||||
</bean>
|
||||
|
||||
Reference in New Issue
Block a user