Browse Source

Removed scheduling.timer and scheduling.backportconcurrent packages

pull/263/head
Juergen Hoeller 13 years ago
parent
commit
3f35bdc79a
  1. 138
      spring-context/src/main/java/org/springframework/scheduling/backportconcurrent/ConcurrentTaskExecutor.java
  2. 61
      spring-context/src/main/java/org/springframework/scheduling/backportconcurrent/CustomizableThreadFactory.java
  3. 385
      spring-context/src/main/java/org/springframework/scheduling/backportconcurrent/ThreadPoolTaskExecutor.java
  4. 11
      spring-context/src/main/java/org/springframework/scheduling/backportconcurrent/package-info.java
  5. 3
      spring-context/src/main/java/org/springframework/scheduling/support/MethodInvokingRunnable.java
  6. 78
      spring-context/src/main/java/org/springframework/scheduling/timer/DelegatingTimerTask.java
  7. 68
      spring-context/src/main/java/org/springframework/scheduling/timer/MethodInvokingTimerTaskFactoryBean.java
  8. 226
      spring-context/src/main/java/org/springframework/scheduling/timer/ScheduledTimerTask.java
  9. 169
      spring-context/src/main/java/org/springframework/scheduling/timer/TimerFactoryBean.java
  10. 184
      spring-context/src/main/java/org/springframework/scheduling/timer/TimerTaskExecutor.java
  11. 10
      spring-context/src/main/java/org/springframework/scheduling/timer/package-info.java
  12. 49
      spring-context/src/test/java/org/springframework/scheduling/backportconcurrent/ConcurrentTaskExecutorTests.java
  13. 133
      spring-context/src/test/java/org/springframework/scheduling/timer/TimerSupportTests.java
  14. 190
      spring-context/src/test/java/org/springframework/scheduling/timer/TimerTaskExecutorTests.java

138
spring-context/src/main/java/org/springframework/scheduling/backportconcurrent/ConcurrentTaskExecutor.java

@ -1,138 +0,0 @@ @@ -1,138 +0,0 @@
/*
* Copyright 2002-2012 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.scheduling.backportconcurrent;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import edu.emory.mathcs.backport.java.util.concurrent.Executor;
import edu.emory.mathcs.backport.java.util.concurrent.Executors;
import edu.emory.mathcs.backport.java.util.concurrent.RejectedExecutionException;
import org.springframework.core.task.TaskRejectedException;
import org.springframework.scheduling.SchedulingTaskExecutor;
/**
* Adapter that takes a JSR-166 backport
* {@code edu.emory.mathcs.backport.java.util.concurrent.Executor} and
* exposes a Spring {@link org.springframework.core.task.TaskExecutor} for it.
*
* <p><b>NOTE:</b> This class implements Spring's
* {@link org.springframework.core.task.TaskExecutor} interface (and hence implicitly
* the standard Java 5 {@link java.util.concurrent.Executor} interface) as well as
* the JSR-166 {@link edu.emory.mathcs.backport.java.util.concurrent.Executor}
* interface, with the former being the primary interface, the other just
* serving as secondary convenience. For this reason, the exception handling
* follows the TaskExecutor contract rather than the backport Executor contract, in
* particular regarding the {@link org.springframework.core.task.TaskRejectedException}.
*
* <p>Note that there is a pre-built {@link ThreadPoolTaskExecutor} that allows for
* defining a JSR-166 backport
* {@link edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor} in bean
* style, exposing it as a Spring {@link org.springframework.core.task.TaskExecutor}
* directly. This is a convenient alternative to a raw ThreadPoolExecutor
* definition with a separate definition of the present adapter class.
*
* @author Juergen Hoeller
* @since 2.0.3
* @see edu.emory.mathcs.backport.java.util.concurrent.Executor
* @see edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor
* @see edu.emory.mathcs.backport.java.util.concurrent.Executors
* @see ThreadPoolTaskExecutor
* @deprecated as of Spring 3.2, in favor of using the native JDK 6 concurrent support
*/
@Deprecated
public class ConcurrentTaskExecutor implements SchedulingTaskExecutor, Executor {
private Executor concurrentExecutor;
/**
* Create a new ConcurrentTaskExecutor,
* using a single thread executor as default.
* @see edu.emory.mathcs.backport.java.util.concurrent.Executors#newSingleThreadExecutor()
*/
public ConcurrentTaskExecutor() {
setConcurrentExecutor(null);
}
/**
* Create a new ConcurrentTaskExecutor,
* using the given JSR-166 backport concurrent executor.
* @param concurrentExecutor the JSR-166 backport concurrent executor to delegate to
*/
public ConcurrentTaskExecutor(Executor concurrentExecutor) {
setConcurrentExecutor(concurrentExecutor);
}
/**
* Specify the JSR-166 backport concurrent executor to delegate to.
*/
public final void setConcurrentExecutor(Executor concurrentExecutor) {
this.concurrentExecutor =
(concurrentExecutor != null ? concurrentExecutor : Executors.newSingleThreadExecutor());
}
/**
* Return the JSR-166 backport concurrent executor that this adapter
* delegates to.
*/
public final Executor getConcurrentExecutor() {
return this.concurrentExecutor;
}
/**
* Delegates to the specified JSR-166 backport concurrent executor.
* @see edu.emory.mathcs.backport.java.util.concurrent.Executor#execute(Runnable)
*/
public void execute(Runnable task) {
try {
this.concurrentExecutor.execute(task);
}
catch (RejectedExecutionException ex) {
throw new TaskRejectedException(
"Executor [" + this.concurrentExecutor + "] did not accept task: " + task, ex);
}
}
public void execute(Runnable task, long startTimeout) {
execute(task);
}
public Future<?> submit(Runnable task) {
FutureTask<Object> future = new FutureTask<Object>(task, null);
execute(future);
return future;
}
public <T> Future<T> submit(Callable<T> task) {
FutureTask<T> future = new FutureTask<T>(task);
execute(future);
return future;
}
/**
* This task executor prefers short-lived work units.
*/
public boolean prefersShortLivedTasks() {
return true;
}
}

61
spring-context/src/main/java/org/springframework/scheduling/backportconcurrent/CustomizableThreadFactory.java

@ -1,61 +0,0 @@ @@ -1,61 +0,0 @@
/*
* Copyright 2002-2012 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.scheduling.backportconcurrent;
import edu.emory.mathcs.backport.java.util.concurrent.ThreadFactory;
import org.springframework.util.CustomizableThreadCreator;
/**
* Implementation of the JSR-166 backport
* {@link edu.emory.mathcs.backport.java.util.concurrent.ThreadFactory} interface,
* allowing for customizing the created threads (name, priority, etc).
*
* <p>See the base class {@link org.springframework.util.CustomizableThreadCreator}
* for details on the available configuration options.
*
* @author Juergen Hoeller
* @since 2.0.3
* @see #setThreadNamePrefix
* @see #setThreadPriority
* @deprecated as of Spring 3.2, in favor of using the native JDK 6 concurrent support
*/
@SuppressWarnings("serial")
@Deprecated
public class CustomizableThreadFactory extends CustomizableThreadCreator implements ThreadFactory {
/**
* Create a new CustomizableThreadFactory with default thread name prefix.
*/
public CustomizableThreadFactory() {
super();
}
/**
* Create a new CustomizableThreadFactory with the given thread name prefix.
* @param threadNamePrefix the prefix to use for the names of newly created threads
*/
public CustomizableThreadFactory(String threadNamePrefix) {
super(threadNamePrefix);
}
public Thread newThread(Runnable runnable) {
return createThread(runnable);
}
}

385
spring-context/src/main/java/org/springframework/scheduling/backportconcurrent/ThreadPoolTaskExecutor.java

@ -1,385 +0,0 @@ @@ -1,385 +0,0 @@
/*
* Copyright 2002-2012 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.scheduling.backportconcurrent;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import edu.emory.mathcs.backport.java.util.concurrent.BlockingQueue;
import edu.emory.mathcs.backport.java.util.concurrent.Executor;
import edu.emory.mathcs.backport.java.util.concurrent.LinkedBlockingQueue;
import edu.emory.mathcs.backport.java.util.concurrent.RejectedExecutionException;
import edu.emory.mathcs.backport.java.util.concurrent.RejectedExecutionHandler;
import edu.emory.mathcs.backport.java.util.concurrent.SynchronousQueue;
import edu.emory.mathcs.backport.java.util.concurrent.ThreadFactory;
import edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor;
import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.task.TaskRejectedException;
import org.springframework.scheduling.SchedulingTaskExecutor;
import org.springframework.util.Assert;
/**
* JavaBean that allows for configuring a JSR-166 backport
* {@link edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor} in bean
* style (through its "corePoolSize", "maxPoolSize", "keepAliveSeconds", "queueCapacity"
* properties), exposing it as a Spring {@link org.springframework.core.task.TaskExecutor}.
* This is an alternative to configuring a ThreadPoolExecutor instance directly using
* constructor injection, with a separate {@link ConcurrentTaskExecutor} adapter wrapping it.
*
* <p>For any custom needs, in particular for defining a
* {@link edu.emory.mathcs.backport.java.util.concurrent.ScheduledThreadPoolExecutor},
* it is recommended to use a straight definition of the Executor instance or a
* factory method definition that points to the JSR-166 backport
* {@link edu.emory.mathcs.backport.java.util.concurrent.Executors} class.
* To expose such a raw Executor as a Spring {@link org.springframework.core.task.TaskExecutor},
* simply wrap it with a {@link ConcurrentTaskExecutor} adapter.
*
* <p><b>NOTE:</b> This class implements Spring's
* {@link org.springframework.core.task.TaskExecutor} interface (and hence implicitly
* the standard Java 5 {@link java.util.concurrent.Executor} interface) as well as
* the JSR-166 {@link edu.emory.mathcs.backport.java.util.concurrent.Executor}
* interface, with the former being the primary interface, the other just
* serving as secondary convenience. For this reason, the exception handling
* follows the TaskExecutor contract rather than the backport Executor contract, in
* particular regarding the {@link org.springframework.core.task.TaskRejectedException}.
*
* @author Juergen Hoeller
* @since 2.0.3
* @see org.springframework.core.task.TaskExecutor
* @see edu.emory.mathcs.backport.java.util.concurrent.Executor
* @see edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor
* @see edu.emory.mathcs.backport.java.util.concurrent.ScheduledThreadPoolExecutor
* @see edu.emory.mathcs.backport.java.util.concurrent.Executors
* @see ConcurrentTaskExecutor
* @deprecated as of Spring 3.2, in favor of using the native JDK 6 concurrent support
*/
@Deprecated
@SuppressWarnings("serial")
public class ThreadPoolTaskExecutor extends CustomizableThreadFactory
implements SchedulingTaskExecutor, Executor, BeanNameAware, InitializingBean, DisposableBean {
protected final Log logger = LogFactory.getLog(getClass());
private final Object poolSizeMonitor = new Object();
private int corePoolSize = 1;
private int maxPoolSize = Integer.MAX_VALUE;
private int keepAliveSeconds = 60;
private boolean allowCoreThreadTimeOut = false;
private int queueCapacity = Integer.MAX_VALUE;
private ThreadFactory threadFactory = this;
private RejectedExecutionHandler rejectedExecutionHandler = new ThreadPoolExecutor.AbortPolicy();
private boolean waitForTasksToCompleteOnShutdown = false;
private boolean threadNamePrefixSet = false;
private String beanName;
private ThreadPoolExecutor threadPoolExecutor;
/**
* Set the ThreadPoolExecutor's core pool size.
* Default is 1.
* <p><b>This setting can be modified at runtime, for example through JMX.</b>
*/
public void setCorePoolSize(int corePoolSize) {
synchronized (this.poolSizeMonitor) {
this.corePoolSize = corePoolSize;
if (this.threadPoolExecutor != null) {
this.threadPoolExecutor.setCorePoolSize(corePoolSize);
}
}
}
/**
* Return the ThreadPoolExecutor's core pool size.
*/
public int getCorePoolSize() {
synchronized (this.poolSizeMonitor) {
return this.corePoolSize;
}
}
/**
* Set the ThreadPoolExecutor's maximum pool size.
* Default is {@code Integer.MAX_VALUE}.
* <p><b>This setting can be modified at runtime, for example through JMX.</b>
*/
public void setMaxPoolSize(int maxPoolSize) {
synchronized (this.poolSizeMonitor) {
this.maxPoolSize = maxPoolSize;
if (this.threadPoolExecutor != null) {
this.threadPoolExecutor.setMaximumPoolSize(maxPoolSize);
}
}
}
/**
* Return the ThreadPoolExecutor's maximum pool size.
*/
public int getMaxPoolSize() {
synchronized (this.poolSizeMonitor) {
return this.maxPoolSize;
}
}
/**
* Set the ThreadPoolExecutor's keep-alive seconds.
* Default is 60.
* <p><b>This setting can be modified at runtime, for example through JMX.</b>
*/
public void setKeepAliveSeconds(int keepAliveSeconds) {
synchronized (this.poolSizeMonitor) {
this.keepAliveSeconds = keepAliveSeconds;
if (this.threadPoolExecutor != null) {
this.threadPoolExecutor.setKeepAliveTime(keepAliveSeconds, TimeUnit.SECONDS);
}
}
}
/**
* Return the ThreadPoolExecutor's keep-alive seconds.
*/
public int getKeepAliveSeconds() {
synchronized (this.poolSizeMonitor) {
return this.keepAliveSeconds;
}
}
/**
* Specify whether to allow core threads to time out. This enables dynamic
* growing and shrinking even in combination with a non-zero queue (since
* the max pool size will only grow once the queue is full).
* <p>Default is "false". Note that this feature is only available on
* backport-concurrent 3.0 or above (based on the code in Java 6).
* @see edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor#allowCoreThreadTimeOut(boolean)
*/
public void setAllowCoreThreadTimeOut(boolean allowCoreThreadTimeOut) {
this.allowCoreThreadTimeOut = allowCoreThreadTimeOut;
}
/**
* Set the capacity for the ThreadPoolExecutor's BlockingQueue.
* Default is {@code Integer.MAX_VALUE}.
* <p>Any positive value will lead to a LinkedBlockingQueue instance;
* any other value will lead to a SynchronousQueue instance.
* @see edu.emory.mathcs.backport.java.util.concurrent.LinkedBlockingQueue
* @see edu.emory.mathcs.backport.java.util.concurrent.SynchronousQueue
*/
public void setQueueCapacity(int queueCapacity) {
this.queueCapacity = queueCapacity;
}
/**
* Set the ThreadFactory to use for the ThreadPoolExecutor's thread pool.
* <p>Default is this executor itself (i.e. the factory that this executor
* inherits from). See {@link org.springframework.util.CustomizableThreadCreator}'s
* javadoc for available bean properties.
* @see #setThreadPriority
* @see #setDaemon
*/
public void setThreadFactory(ThreadFactory threadFactory) {
this.threadFactory = (threadFactory != null ? threadFactory : this);
}
/**
* Set the RejectedExecutionHandler to use for the ThreadPoolExecutor.
* Default is the ThreadPoolExecutor's default abort policy.
* @see edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor.AbortPolicy
*/
public void setRejectedExecutionHandler(RejectedExecutionHandler rejectedExecutionHandler) {
this.rejectedExecutionHandler =
(rejectedExecutionHandler != null ? rejectedExecutionHandler : new ThreadPoolExecutor.AbortPolicy());
}
/**
* Set whether to wait for scheduled tasks to complete on shutdown.
* <p>Default is "false". Switch this to "true" if you prefer
* fully completed tasks at the expense of a longer shutdown phase.
* @see edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor#shutdown()
* @see edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor#shutdownNow()
*/
public void setWaitForTasksToCompleteOnShutdown(boolean waitForJobsToCompleteOnShutdown) {
this.waitForTasksToCompleteOnShutdown = waitForJobsToCompleteOnShutdown;
}
@Override
public void setThreadNamePrefix(String threadNamePrefix) {
super.setThreadNamePrefix(threadNamePrefix);
this.threadNamePrefixSet = true;
}
public void setBeanName(String name) {
this.beanName = name;
}
/**
* Calls {@code initialize()} after the container applied all property values.
* @see #initialize()
*/
public void afterPropertiesSet() {
initialize();
}
/**
* Creates the BlockingQueue and the ThreadPoolExecutor.
* @see #createQueue
*/
public void initialize() {
if (logger.isInfoEnabled()) {
logger.info("Initializing ThreadPoolExecutor" + (this.beanName != null ? " '" + this.beanName + "'" : ""));
}
if (!this.threadNamePrefixSet && this.beanName != null) {
setThreadNamePrefix(this.beanName + "-");
}
BlockingQueue queue = createQueue(this.queueCapacity);
this.threadPoolExecutor = new ThreadPoolExecutor(
this.corePoolSize, this.maxPoolSize, this.keepAliveSeconds, TimeUnit.SECONDS,
queue, this.threadFactory, this.rejectedExecutionHandler);
if (this.allowCoreThreadTimeOut) {
this.threadPoolExecutor.allowCoreThreadTimeOut(true);
}
}
/**
* Create the BlockingQueue to use for the ThreadPoolExecutor.
* <p>A LinkedBlockingQueue instance will be created for a positive
* capacity value; a SynchronousQueue else.
* @param queueCapacity the specified queue capacity
* @return the BlockingQueue instance
* @see edu.emory.mathcs.backport.java.util.concurrent.LinkedBlockingQueue
* @see edu.emory.mathcs.backport.java.util.concurrent.SynchronousQueue
*/
protected BlockingQueue createQueue(int queueCapacity) {
if (queueCapacity > 0) {
return new LinkedBlockingQueue(queueCapacity);
}
else {
return new SynchronousQueue();
}
}
/**
* Return the underlying ThreadPoolExecutor for native access.
* @return the underlying ThreadPoolExecutor (never {@code null})
* @throws IllegalStateException if the ThreadPoolTaskExecutor hasn't been initialized yet
*/
public ThreadPoolExecutor getThreadPoolExecutor() throws IllegalStateException {
Assert.state(this.threadPoolExecutor != null, "ThreadPoolTaskExecutor not initialized");
return this.threadPoolExecutor;
}
/**
* Implementation of both the JSR-166 backport Executor interface and the Spring
* TaskExecutor interface, delegating to the ThreadPoolExecutor instance.
* @see edu.emory.mathcs.backport.java.util.concurrent.Executor#execute(Runnable)
* @see org.springframework.core.task.TaskExecutor#execute(Runnable)
*/
public void execute(Runnable task) {
Executor executor = getThreadPoolExecutor();
try {
executor.execute(task);
}
catch (RejectedExecutionException ex) {
throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, ex);
}
}
public void execute(Runnable task, long startTimeout) {
execute(task);
}
public Future<?> submit(Runnable task) {
FutureTask<Object> future = new FutureTask<Object>(task, null);
execute(future);
return future;
}
public <T> Future<T> submit(Callable<T> task) {
FutureTask<T> future = new FutureTask<T>(task);
execute(future);
return future;
}
/**
* This task executor prefers short-lived work units.
*/
public boolean prefersShortLivedTasks() {
return true;
}
/**
* Return the current pool size.
* @see edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor#getPoolSize()
*/
public int getPoolSize() {
return getThreadPoolExecutor().getPoolSize();
}
/**
* Return the number of currently active threads.
* @see edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor#getActiveCount()
*/
public int getActiveCount() {
return getThreadPoolExecutor().getActiveCount();
}
/**
* Calls {@code shutdown} when the BeanFactory destroys
* the task executor instance.
* @see #shutdown()
*/
public void destroy() {
shutdown();
}
/**
* Perform a shutdown on the ThreadPoolExecutor.
* @see edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor#shutdown()
*/
public void shutdown() {
if (logger.isInfoEnabled()) {
logger.info("Shutting down ThreadPoolExecutor" + (this.beanName != null ? " '" + this.beanName + "'" : ""));
}
if (this.waitForTasksToCompleteOnShutdown) {
this.threadPoolExecutor.shutdown();
}
else {
this.threadPoolExecutor.shutdownNow();
}
}
}

11
spring-context/src/main/java/org/springframework/scheduling/backportconcurrent/package-info.java

@ -1,11 +0,0 @@ @@ -1,11 +0,0 @@
/**
*
* Scheduling convenience classes for the
* <a href="http://dcl.mathcs.emory.edu/util/backport-util-concurrent/">JSR-166 backport</a>
* Executor mechanism, allowing to set up a ThreadPoolExecutor
* as a TaskExecutor-compliant bean in a Spring context.
*
*/
package org.springframework.scheduling.backportconcurrent;

3
spring-context/src/main/java/org/springframework/scheduling/support/MethodInvokingRunnable.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 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.
@ -35,7 +35,6 @@ import org.springframework.util.ClassUtils; @@ -35,7 +35,6 @@ import org.springframework.util.ClassUtils;
*
* @author Juergen Hoeller
* @since 1.2.4
* @see org.springframework.scheduling.timer.ScheduledTimerTask#setRunnable(Runnable)
* @see java.util.concurrent.Executor#execute(Runnable)
*/
public class MethodInvokingRunnable extends ArgumentConvertingMethodInvoker

78
spring-context/src/main/java/org/springframework/scheduling/timer/DelegatingTimerTask.java

@ -1,78 +0,0 @@ @@ -1,78 +0,0 @@
/*
* Copyright 2002-2012 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.scheduling.timer;
import java.util.TimerTask;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
/**
* Simple {@link java.util.TimerTask} adapter that delegates to a
* given {@link Runnable}.
*
* <p>This is often preferable to deriving from TimerTask, to be able to
* implement an interface rather than extend an abstract base class.
*
* @author Juergen Hoeller
* @since 1.2.4
* @deprecated as of Spring 3.0, in favor of the {@code scheduling.concurrent}
* package which is based on Java 5's {@code java.util.concurrent.ExecutorService}
*/
@Deprecated
public class DelegatingTimerTask extends TimerTask {
private static final Log logger = LogFactory.getLog(DelegatingTimerTask.class);
private final Runnable delegate;
/**
* Create a new DelegatingTimerTask.
* @param delegate the Runnable implementation to delegate to
*/
public DelegatingTimerTask(Runnable delegate) {
Assert.notNull(delegate, "Delegate must not be null");
this.delegate = delegate;
}
/**
* Return the wrapped Runnable implementation.
*/
public final Runnable getDelegate() {
return this.delegate;
}
/**
* Delegates execution to the underlying Runnable, catching any exception
* or error thrown in order to continue scheduled execution.
*/
@Override
public void run() {
try {
this.delegate.run();
}
catch (Throwable ex) {
logger.error("Unexpected exception thrown from Runnable: " + this.delegate, ex);
// Do not throw the exception, else the main loop of the Timer might stop!
}
}
}

68
spring-context/src/main/java/org/springframework/scheduling/timer/MethodInvokingTimerTaskFactoryBean.java

@ -1,68 +0,0 @@ @@ -1,68 +0,0 @@
/*
* Copyright 2002-2012 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.scheduling.timer;
import java.util.TimerTask;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.scheduling.support.MethodInvokingRunnable;
/**
* {@link FactoryBean} that exposes a {@link TimerTask} object which
* delegates job execution to a specified (static or non-static) method.
* Avoids the need to implement a one-line TimerTask that just invokes
* an existing business method.
*
* <p>Derives from {@link MethodInvokingRunnable} to share common properties
* and behavior, effectively providing a TimerTask adapter for it.
*
* @author Juergen Hoeller
* @since 19.02.2004
* @see DelegatingTimerTask
* @see ScheduledTimerTask#setTimerTask
* @see ScheduledTimerTask#setRunnable
* @see org.springframework.scheduling.support.MethodInvokingRunnable
* @see org.springframework.beans.factory.config.MethodInvokingFactoryBean
* @deprecated as of Spring 3.0, in favor of the {@code scheduling.concurrent}
* package which is based on Java 5's {@code java.util.concurrent.ExecutorService}
*/
@Deprecated
public class MethodInvokingTimerTaskFactoryBean extends MethodInvokingRunnable implements FactoryBean<TimerTask> {
private TimerTask timerTask;
@Override
public void afterPropertiesSet() throws ClassNotFoundException, NoSuchMethodException {
super.afterPropertiesSet();
this.timerTask = new DelegatingTimerTask(this);
}
public TimerTask getObject() {
return this.timerTask;
}
public Class<TimerTask> getObjectType() {
return TimerTask.class;
}
public boolean isSingleton() {
return true;
}
}

226
spring-context/src/main/java/org/springframework/scheduling/timer/ScheduledTimerTask.java

@ -1,226 +0,0 @@ @@ -1,226 +0,0 @@
/*
* Copyright 2002-2012 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.scheduling.timer;
import java.util.TimerTask;
/**
* JavaBean that describes a scheduled {@link TimerTask}, consisting of the
* {@link TimerTask} itself or a {@link Runnable} to create a {@link TimerTask}
* for and a delay plus period. The period needs to be specified; there is
* no point in a default for it.
*
* <p>The JDK's {@link java.util.Timer} facility does not offer sophisticated
* scheduling options such as cron expressions. Consider using Quartz for
* such advanced needs.
*
* <p>Note that the {@link java.util.Timer} mechanism uses a {@link TimerTask}
* instance that is shared between repeated executions, in contrast to Quartz
* which creates a new Job instance for each execution.
*
* @author Juergen Hoeller
* @since 19.02.2004
* @see java.util.TimerTask
* @see java.util.Timer#schedule(TimerTask, long, long)
* @see java.util.Timer#scheduleAtFixedRate(TimerTask, long, long)
* @deprecated as of Spring 3.0, in favor of the {@code scheduling.concurrent}
* package which is based on Java 5's {@code java.util.concurrent.ExecutorService}
*/
@Deprecated
public class ScheduledTimerTask {
private TimerTask timerTask;
private long delay = 0;
private long period = -1;
private boolean fixedRate = false;
/**
* Create a new ScheduledTimerTask,
* to be populated via bean properties.
* @see #setTimerTask
* @see #setDelay
* @see #setPeriod
* @see #setFixedRate
*/
public ScheduledTimerTask() {
}
/**
* Create a new ScheduledTimerTask, with default
* one-time execution without delay.
* @param timerTask the TimerTask to schedule
*/
public ScheduledTimerTask(TimerTask timerTask) {
this.timerTask = timerTask;
}
/**
* Create a new ScheduledTimerTask, with default
* one-time execution with the given delay.
* @param timerTask the TimerTask to schedule
* @param delay the delay before starting the task for the first time (ms)
*/
public ScheduledTimerTask(TimerTask timerTask, long delay) {
this.timerTask = timerTask;
this.delay = delay;
}
/**
* Create a new ScheduledTimerTask.
* @param timerTask the TimerTask to schedule
* @param delay the delay before starting the task for the first time (ms)
* @param period the period between repeated task executions (ms)
* @param fixedRate whether to schedule as fixed-rate execution
*/
public ScheduledTimerTask(TimerTask timerTask, long delay, long period, boolean fixedRate) {
this.timerTask = timerTask;
this.delay = delay;
this.period = period;
this.fixedRate = fixedRate;
}
/**
* Create a new ScheduledTimerTask, with default
* one-time execution without delay.
* @param timerTask the Runnable to schedule as TimerTask
*/
public ScheduledTimerTask(Runnable timerTask) {
setRunnable(timerTask);
}
/**
* Create a new ScheduledTimerTask, with default
* one-time execution with the given delay.
* @param timerTask the Runnable to schedule as TimerTask
* @param delay the delay before starting the task for the first time (ms)
*/
public ScheduledTimerTask(Runnable timerTask, long delay) {
setRunnable(timerTask);
this.delay = delay;
}
/**
* Create a new ScheduledTimerTask.
* @param timerTask the Runnable to schedule as TimerTask
* @param delay the delay before starting the task for the first time (ms)
* @param period the period between repeated task executions (ms)
* @param fixedRate whether to schedule as fixed-rate execution
*/
public ScheduledTimerTask(Runnable timerTask, long delay, long period, boolean fixedRate) {
setRunnable(timerTask);
this.delay = delay;
this.period = period;
this.fixedRate = fixedRate;
}
/**
* Set the Runnable to schedule as TimerTask.
* @see DelegatingTimerTask
*/
public void setRunnable(Runnable timerTask) {
this.timerTask = new DelegatingTimerTask(timerTask);
}
/**
* Set the TimerTask to schedule.
*/
public void setTimerTask(TimerTask timerTask) {
this.timerTask = timerTask;
}
/**
* Return the TimerTask to schedule.
*/
public TimerTask getTimerTask() {
return this.timerTask;
}
/**
* Set the delay before starting the task for the first time,
* in milliseconds. Default is 0, immediately starting the
* task after successful scheduling.
*/
public void setDelay(long delay) {
this.delay = delay;
}
/**
* Return the delay before starting the job for the first time.
*/
public long getDelay() {
return this.delay;
}
/**
* Set the period between repeated task executions, in milliseconds.
* <p>Default is -1, leading to one-time execution. In case of a positive
* value, the task will be executed repeatedly, with the given interval
* inbetween executions.
* <p>Note that the semantics of the period value vary between fixed-rate
* and fixed-delay execution.
* <p><b>Note:</b> A period of 0 (for example as fixed delay) is <i>not</i>
* supported, simply because {@code java.util.Timer} itself does not
* support it. Hence a value of 0 will be treated as one-time execution;
* however, that value should never be specified explicitly in the first place!
* @see #setFixedRate
* @see #isOneTimeTask()
* @see java.util.Timer#schedule(TimerTask, long, long)
*/
public void setPeriod(long period) {
this.period = period;
}
/**
* Return the period between repeated task executions.
*/
public long getPeriod() {
return this.period;
}
/**
* Is this task only ever going to execute once?
* @return {@code true} if this task is only ever going to execute once
* @see #getPeriod()
*/
public boolean isOneTimeTask() {
return (this.period <= 0);
}
/**
* Set whether to schedule as fixed-rate execution, rather than
* fixed-delay execution. Default is "false", that is, fixed delay.
* <p>See Timer javadoc for details on those execution modes.
* @see java.util.Timer#schedule(TimerTask, long, long)
* @see java.util.Timer#scheduleAtFixedRate(TimerTask, long, long)
*/
public void setFixedRate(boolean fixedRate) {
this.fixedRate = fixedRate;
}
/**
* Return whether to schedule as fixed-rate execution.
*/
public boolean isFixedRate() {
return this.fixedRate;
}
}

169
spring-context/src/main/java/org/springframework/scheduling/timer/TimerFactoryBean.java

@ -1,169 +0,0 @@ @@ -1,169 +0,0 @@
/*
* Copyright 2002-2012 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.scheduling.timer;
import java.util.Timer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
/**
* FactoryBean that sets up a {@link java.util.Timer} and exposes it for bean references.
*
* <p>Allows for registration of {@link ScheduledTimerTask ScheduledTimerTasks},
* automatically starting the {@link Timer} on initialization and cancelling it
* on destruction of the context. In scenarios that just require static registration
* of tasks at startup, there is no need to access the {@link Timer} instance itself
* in application code at all.
*
* <p>Note that the {@link Timer} mechanism uses a {@link java.util.TimerTask}
* instance that is shared between repeated executions, in contrast to Quartz
* which creates a new Job instance for each execution.
*
* @author Juergen Hoeller
* @since 19.02.2004
* @see ScheduledTimerTask
* @see java.util.Timer
* @see java.util.TimerTask
* @deprecated as of Spring 3.0, in favor of the {@code scheduling.concurrent}
* package which is based on Java 5's {@code java.util.concurrent.ExecutorService}
*/
@Deprecated
public class TimerFactoryBean implements FactoryBean<Timer>, BeanNameAware, InitializingBean, DisposableBean {
protected final Log logger = LogFactory.getLog(getClass());
private ScheduledTimerTask[] scheduledTimerTasks;
private boolean daemon = false;
private String beanName;
private Timer timer;
/**
* Register a list of ScheduledTimerTask objects with the Timer that
* this FactoryBean creates. Depending on each SchedulerTimerTask's
* settings, it will be registered via one of Timer's schedule methods.
* @see java.util.Timer#schedule(java.util.TimerTask, long)
* @see java.util.Timer#schedule(java.util.TimerTask, long, long)
* @see java.util.Timer#scheduleAtFixedRate(java.util.TimerTask, long, long)
*/
public void setScheduledTimerTasks(ScheduledTimerTask[] scheduledTimerTasks) {
this.scheduledTimerTasks = scheduledTimerTasks;
}
/**
* Set whether the timer should use a daemon thread,
* just executing as long as the application itself is running.
* <p>Default is "false": The timer will automatically get cancelled on
* destruction of this FactoryBean. Hence, if the application shuts down,
* tasks will by default finish their execution. Specify "true" for eager
* shutdown of threads that execute tasks.
* @see java.util.Timer#Timer(boolean)
*/
public void setDaemon(boolean daemon) {
this.daemon = daemon;
}
public void setBeanName(String beanName) {
this.beanName = beanName;
}
public void afterPropertiesSet() {
logger.info("Initializing Timer");
this.timer = createTimer(this.beanName, this.daemon);
// Register specified ScheduledTimerTasks, if necessary.
if (!ObjectUtils.isEmpty(this.scheduledTimerTasks)) {
registerTasks(this.scheduledTimerTasks, this.timer);
}
}
/**
* Create a new Timer instance. Called by {@code afterPropertiesSet}.
* Can be overridden in subclasses to provide custom Timer subclasses.
* @param name the desired name of the Timer's associated thread
* @param daemon whether to create a Timer that runs as daemon thread
* @return a new Timer instance
* @see #afterPropertiesSet()
* @see java.util.Timer#Timer(boolean)
*/
protected Timer createTimer(String name, boolean daemon) {
if (StringUtils.hasText(name)) {
return new Timer(name, daemon);
}
else {
return new Timer(daemon);
}
}
/**
* Register the specified {@link ScheduledTimerTask ScheduledTimerTasks}
* on the given {@link Timer}.
* @param tasks the specified ScheduledTimerTasks (never empty)
* @param timer the Timer to register the tasks on.
*/
protected void registerTasks(ScheduledTimerTask[] tasks, Timer timer) {
for (ScheduledTimerTask task : tasks) {
if (task.isOneTimeTask()) {
timer.schedule(task.getTimerTask(), task.getDelay());
}
else {
if (task.isFixedRate()) {
timer.scheduleAtFixedRate(task.getTimerTask(), task.getDelay(), task.getPeriod());
}
else {
timer.schedule(task.getTimerTask(), task.getDelay(), task.getPeriod());
}
}
}
}
public Timer getObject() {
return this.timer;
}
public Class<? extends Timer> getObjectType() {
return Timer.class;
}
public boolean isSingleton() {
return true;
}
/**
* Cancel the Timer on bean factory shutdown, stopping all scheduled tasks.
* @see java.util.Timer#cancel()
*/
public void destroy() {
logger.info("Cancelling Timer");
this.timer.cancel();
}
}

184
spring-context/src/main/java/org/springframework/scheduling/timer/TimerTaskExecutor.java

@ -1,184 +0,0 @@ @@ -1,184 +0,0 @@
/*
* Copyright 2002-2012 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.scheduling.timer;
import java.util.Timer;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.scheduling.SchedulingTaskExecutor;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* {@link org.springframework.core.task.TaskExecutor} implementation that uses a
* single {@link Timer} for executing all tasks, effectively resulting in
* serialized asynchronous execution on a single thread.
*
* @author Juergen Hoeller
* @since 2.0
* @see java.util.Timer
* @deprecated as of Spring 3.0, in favor of the {@code scheduling.concurrent}
* package which is based on Java 5's {@code java.util.concurrent.ExecutorService}
*/
@Deprecated
public class TimerTaskExecutor implements SchedulingTaskExecutor, BeanNameAware, InitializingBean, DisposableBean {
protected final Log logger = LogFactory.getLog(getClass());
private Timer timer;
private long delay = 0;
private String beanName;
private boolean timerInternal = false;
/**
* Create a new TimerTaskExecutor that needs to be further configured and initialized.
* @see #setTimer
* @see #afterPropertiesSet
*/
public TimerTaskExecutor() {
}
/**
* Create a new TimerTaskExecutor for the given {@link Timer}.
* @param timer the {@link Timer} to wrap
*/
public TimerTaskExecutor(Timer timer) {
Assert.notNull(timer, "Timer must not be null");
this.timer = timer;
}
/**
* Set the {@link Timer} to use for this {@link TimerTaskExecutor}, for example
* a shared {@link Timer} instance defined by a {@link TimerFactoryBean}.
* <p>If not specified, a default internal {@link Timer} instance will be used.
* @param timer the {@link Timer} to use for this {@link TimerTaskExecutor}
* @see TimerFactoryBean
*/
public void setTimer(Timer timer) {
this.timer = timer;
}
/**
* Set the delay to use for scheduling tasks passed into the plain
* {@link #execute(Runnable)} method. Default is 0.
* <p>Note that calls to {@link #execute(Runnable, long)} will use the
* given timeout as delay if it is lower than the general delay.
* @param delay the delay in milliseconds before the task is to be executed
*/
public void setDelay(long delay) {
this.delay = delay;
}
public void setBeanName(String beanName) {
this.beanName = beanName;
}
public void afterPropertiesSet() {
if (this.timer == null) {
logger.info("Initializing Timer");
this.timer = createTimer();
this.timerInternal = true;
}
}
/**
* Create a new {@link Timer} instance. Called by {@code afterPropertiesSet}
* if no {@link Timer} has been specified explicitly.
* <p>The default implementation creates a plain non-daemon {@link Timer}.
* If overridden, subclasses must take care to ensure that a non-null
* {@link Timer} is returned from the execution of this method.
* @see #afterPropertiesSet
* @see java.util.Timer#Timer(String, boolean)
*/
protected Timer createTimer() {
if (StringUtils.hasText(this.beanName)) {
return new Timer(this.beanName);
}
else {
return new Timer();
}
}
/**
* Return the underlying Timer behind this TimerTaskExecutor.
*/
protected final Timer getTimer() {
Assert.notNull(this.timer, "Timer not initialized yet");
return this.timer;
}
/**
* Schedules the given {@link Runnable} on this executor's {@link Timer} instance,
* wrapping it in a {@link DelegatingTimerTask}.
* @param task the task to be executed
*/
public void execute(Runnable task) {
getTimer().schedule(new DelegatingTimerTask(task), this.delay);
}
public void execute(Runnable task, long startTimeout) {
long actualDelay = (startTimeout < this.delay ? startTimeout : this.delay);
getTimer().schedule(new DelegatingTimerTask(task), actualDelay);
}
public Future<?> submit(Runnable task) {
FutureTask<Object> future = new FutureTask<Object>(task, null);
execute(future);
return future;
}
public <T> Future<T> submit(Callable<T> task) {
FutureTask<T> future = new FutureTask<T>(task);
execute(future);
return future;
}
/**
* This task executor prefers short-lived work units.
*/
public boolean prefersShortLivedTasks() {
return true;
}
/**
* Cancel the {@link Timer} on bean factory shutdown, stopping all scheduled tasks.
* @see java.util.Timer#cancel()
*/
public void destroy() {
if (this.timerInternal) {
logger.info("Cancelling Timer");
this.timer.cancel();
}
}
}

10
spring-context/src/main/java/org/springframework/scheduling/timer/package-info.java

@ -1,10 +0,0 @@ @@ -1,10 +0,0 @@
/**
*
* Scheduling convenience classes for the JDK Timer,
* allowing to set up Timers and ScheduledTimerTasks
* as beans in a Spring context.
*
*/
package org.springframework.scheduling.timer;

49
spring-context/src/test/java/org/springframework/scheduling/backportconcurrent/ConcurrentTaskExecutorTests.java

@ -1,49 +0,0 @@ @@ -1,49 +0,0 @@
/*
* Copyright 2002-2012 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.scheduling.backportconcurrent;
import junit.framework.TestCase;
import org.springframework.core.task.NoOpRunnable;
/**
* @author Rick Evans
* @author Juergen Hoeller
*/
@Deprecated
public class ConcurrentTaskExecutorTests extends TestCase {
public void testZeroArgCtorResultsInDefaultTaskExecutorBeingUsed() throws Exception {
ConcurrentTaskExecutor executor = new ConcurrentTaskExecutor();
// must not throw a NullPointerException
executor.execute(new NoOpRunnable());
}
public void testPassingNullExecutorToCtorResultsInDefaultTaskExecutorBeingUsed() throws Exception {
ConcurrentTaskExecutor executor = new ConcurrentTaskExecutor(null);
// must not throw a NullPointerException
executor.execute(new NoOpRunnable());
}
public void testPassingNullExecutorToSetterResultsInDefaultTaskExecutorBeingUsed() throws Exception {
ConcurrentTaskExecutor executor = new ConcurrentTaskExecutor();
executor.setConcurrentExecutor(null);
// must not throw a NullPointerException
executor.execute(new NoOpRunnable());
}
}

133
spring-context/src/test/java/org/springframework/scheduling/timer/TimerSupportTests.java

@ -1,133 +0,0 @@ @@ -1,133 +0,0 @@
/*
* Copyright 2002-2013 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.scheduling.timer;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertThat;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import junit.framework.TestCase;
import org.springframework.tests.context.TestMethodInvokingTask;
/**
* @author Juergen Hoeller
* @since 20.02.2004
*/
@Deprecated
public class TimerSupportTests extends TestCase {
public void testTimerFactoryBean() throws Exception {
final TestTimerTask timerTask0 = new TestTimerTask();
TestMethodInvokingTask task1 = new TestMethodInvokingTask();
MethodInvokingTimerTaskFactoryBean mittfb = new MethodInvokingTimerTaskFactoryBean();
mittfb.setTargetObject(task1);
mittfb.setTargetMethod("doSomething");
mittfb.afterPropertiesSet();
final TimerTask timerTask1 = mittfb.getObject();
final TestRunnable timerTask2 = new TestRunnable();
ScheduledTimerTask[] tasks = new ScheduledTimerTask[3];
tasks[0] = new ScheduledTimerTask(timerTask0, 0, 10, false);
tasks[1] = new ScheduledTimerTask(timerTask1, 10, 20, true);
tasks[2] = new ScheduledTimerTask(timerTask2, 20);
final List<Boolean> success = new ArrayList<Boolean>(3);
final Timer timer = new Timer(true) {
@Override
public void schedule(TimerTask task, long delay, long period) {
if (task == timerTask0 && delay == 0 && period == 10) {
success.add(Boolean.TRUE);
}
}
@Override
public void scheduleAtFixedRate(TimerTask task, long delay, long period) {
if (task == timerTask1 && delay == 10 && period == 20) {
success.add(Boolean.TRUE);
}
}
@Override
public void schedule(TimerTask task, long delay) {
if (task instanceof DelegatingTimerTask && delay == 20) {
success.add(Boolean.TRUE);
}
}
@Override
public void cancel() {
success.add(Boolean.TRUE);
}
};
TimerFactoryBean timerFactoryBean = new TimerFactoryBean() {
@Override
protected Timer createTimer(String name, boolean daemon) {
return timer;
}
};
try {
timerFactoryBean.setScheduledTimerTasks(tasks);
timerFactoryBean.afterPropertiesSet();
assertThat(timerFactoryBean.getObject(), instanceOf(Timer.class));
timerTask0.run();
timerTask1.run();
timerTask2.run();
}
finally {
timerFactoryBean.destroy();
}
assertTrue("Correct Timer invocations", success.size() == 4);
assertTrue("TimerTask0 works", timerTask0.counter == 1);
assertTrue("TimerTask1 works", task1.counter == 1);
assertTrue("TimerTask2 works", timerTask2.counter == 1);
}
public void testPlainTimerFactoryBean() {
TimerFactoryBean tfb = new TimerFactoryBean();
tfb.afterPropertiesSet();
tfb.destroy();
}
private static class TestTimerTask extends TimerTask {
private int counter = 0;
@Override
public void run() {
counter++;
}
}
private static class TestRunnable implements Runnable {
private int counter = 0;
@Override
public void run() {
counter++;
}
}
}

190
spring-context/src/test/java/org/springframework/scheduling/timer/TimerTaskExecutorTests.java

@ -1,190 +0,0 @@ @@ -1,190 +0,0 @@
/*
* Copyright 2002-2012 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.scheduling.timer;
import static org.junit.Assert.*;
import java.util.Timer;
import org.junit.Test;
/**
* Unit tests for the {@link TimerTaskExecutor} class.
*
* @author Rick Evans
* @author Chris Beams
*/
@Deprecated
public final class TimerTaskExecutorTests {
@Test(expected=IllegalArgumentException.class)
public void testExecuteChokesWithNullTimer() throws Exception {
TimerTaskExecutor executor = new TimerTaskExecutor();
executor.execute(new NoOpRunnable());
}
@Test(expected=IllegalArgumentException.class)
public void testExecuteChokesWithNullTask() throws Exception {
TimerTaskExecutor executor = new TimerTaskExecutor(new Timer());
executor.execute(null);
}
@Test(expected=IllegalArgumentException.class)
public void testExecuteChokesWithNegativeDelay() throws Exception {
TimerTaskExecutor executor = new TimerTaskExecutor(new Timer());
executor.setDelay(-10);
executor.execute(new NoOpRunnable());
}
@Test
public void testExecuteReallyDoesScheduleTheSuppliedTask() throws Exception {
final Object monitor = new Object();
RunAwareRunnable task = new RunAwareRunnable(monitor);
TimerTaskExecutor executor = new TimerTaskExecutor(new Timer());
executor.execute(task);
synchronized (monitor) {
monitor.wait(5000);
}
assertTrue("Supplied task (a Runnable) is not being invoked.", task.isRunWasCalled());
}
@Test(expected=IllegalArgumentException.class)
public void testCtorWithNullTimer() throws Exception {
new TimerTaskExecutor(null);
}
@Test
public void testCreateTimerMethodIsCalledIfNoTimerIsExplicitlySupplied() throws Exception {
CreationAwareTimerTaskExecutor executor = new CreationAwareTimerTaskExecutor();
executor.afterPropertiesSet();
assertTrue("If no Timer is set explicitly, then the protected createTimer() " +
"method must be called to create the Timer (it obviously isn't being called).",
executor.isCreateTimerWasCalled());
}
@Test
public void testCreateTimerMethodIsNotCalledIfTimerIsExplicitlySupplied() throws Exception {
CreationAwareTimerTaskExecutor executor = new CreationAwareTimerTaskExecutor();
executor.setTimer(new Timer());
executor.afterPropertiesSet();
assertFalse("If a Timer is set explicitly, then the protected createTimer() " +
"method must not be called to create the Timer (it obviously is being called, in error).",
executor.isCreateTimerWasCalled());
}
@Test
public void testThatTheDestroyCallbackCancelsTheTimerIfNoTimerIsExplicitlySupplied() throws Exception {
final CancelAwareTimer timer = new CancelAwareTimer();
TimerTaskExecutor executor = new TimerTaskExecutor() {
@Override
protected Timer createTimer() {
return timer;
}
};
executor.afterPropertiesSet();
executor.destroy();
assertTrue("When the Timer used is created by the TimerTaskExecutor because " +
"no Timer was set explicitly, then the destroy() callback must cancel() said Timer (it obviously isn't doing this).",
timer.isCancelWasCalled());
}
@Test
public void testThatTheDestroyCallbackDoesNotCancelTheTimerIfTheTimerWasSuppliedExplictly() throws Exception {
TimerTaskExecutor executor = new TimerTaskExecutor();
CancelAwareTimer timer = new CancelAwareTimer();
executor.setTimer(timer);
executor.afterPropertiesSet();
executor.destroy();
assertFalse("When the Timer used is not created by the TimerTaskExecutor because " +
"it Timer was set explicitly, then the destroy() callback must NOT cancel() said Timer (it obviously is, in error).",
timer.isCancelWasCalled());
}
private final static class CreationAwareTimerTaskExecutor extends TimerTaskExecutor {
private boolean createTimerWasCalled = false;
public boolean isCreateTimerWasCalled() {
return this.createTimerWasCalled;
}
@Override
protected Timer createTimer() {
this.createTimerWasCalled = true;
return super.createTimer();
}
}
private static class CancelAwareTimer extends Timer {
private boolean cancelWasCalled;
public boolean isCancelWasCalled() {
return this.cancelWasCalled;
}
@Override
public void cancel() {
this.cancelWasCalled = true;
super.cancel();
}
}
private static class RunAwareRunnable implements Runnable {
private boolean runWasCalled;
private final Object monitor;
public RunAwareRunnable(Object monitor) {
this.monitor = monitor;
}
public boolean isRunWasCalled() {
return this.runWasCalled;
}
@Override
public void run() {
this.runWasCalled = true;
synchronized (monitor) {
monitor.notifyAll();
}
}
}
private static final class NoOpRunnable implements Runnable {
@Override
public void run() {
// explicit no-op
}
}
}
Loading…
Cancel
Save