1. /*
  2. * Copyright 2002-2004 the original author or authors.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.springframework.scheduling.timer;
  17. import java.lang.reflect.InvocationTargetException;
  18. import java.util.TimerTask;
  19. import org.apache.commons.logging.Log;
  20. import org.apache.commons.logging.LogFactory;
  21. import org.springframework.beans.factory.FactoryBean;
  22. import org.springframework.beans.factory.InitializingBean;
  23. import org.springframework.util.MethodInvoker;
  24. /**
  25. * FactoryBean that exposes a TimerTask object that delegates
  26. * job execution to a specified (static or non-static) method.
  27. * Avoids the need to implement a one-line TimerTask that just
  28. * invokes an existing business method.
  29. *
  30. * <p>Derived from MethodInvoker to share common properties and
  31. * behavior with MethodInvokingFactoryBean.
  32. *
  33. * @author Juergen Hoeller
  34. * @since 19.02.2004
  35. * @see org.springframework.beans.factory.config.MethodInvokingFactoryBean
  36. */
  37. public class MethodInvokingTimerTaskFactoryBean extends MethodInvoker
  38. implements FactoryBean, InitializingBean {
  39. private TimerTask timerTask;
  40. public void afterPropertiesSet() throws ClassNotFoundException, NoSuchMethodException {
  41. prepare();
  42. this.timerTask = new MethodInvokingTimerTask(this);
  43. }
  44. public Object getObject() {
  45. return this.timerTask;
  46. }
  47. public Class getObjectType() {
  48. return TimerTask.class;
  49. }
  50. public boolean isSingleton() {
  51. return true;
  52. }
  53. /**
  54. * TimerTask implementation that invokes a specified method.
  55. * Automatically applied by MethodInvokingTimerTaskFactoryBean.
  56. */
  57. private static class MethodInvokingTimerTask extends TimerTask {
  58. protected final Log logger = LogFactory.getLog(getClass());
  59. private final MethodInvoker methodInvoker;
  60. private final String errorMessage;
  61. /**
  62. * Create a new MethodInvokingTimerTask with the MethodInvoker to use.
  63. */
  64. private MethodInvokingTimerTask(MethodInvoker methodInvoker) {
  65. this.methodInvoker = methodInvoker;
  66. this.errorMessage = "Invocation of method '" + this.methodInvoker.getTargetMethod() +
  67. "' on target object [" + this.methodInvoker.getTargetObject() + "] failed";
  68. }
  69. /**
  70. * Invoke the method via the MethodInvoker.
  71. */
  72. public void run() {
  73. try {
  74. this.methodInvoker.invoke();
  75. }
  76. catch (InvocationTargetException ex) {
  77. logger.error(this.errorMessage, ex);
  78. // Do not throw exception, else the main loop of the Timer will stop!
  79. }
  80. catch (Throwable ex) {
  81. logger.error(this.errorMessage, ex);
  82. // Do not throw exception, else the main loop of the Timer will stop!
  83. }
  84. }
  85. }
  86. }