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.aop.target;
  17. import org.apache.commons.logging.Log;
  18. import org.apache.commons.logging.LogFactory;
  19. import org.springframework.aop.TargetSource;
  20. import org.springframework.beans.BeansException;
  21. import org.springframework.beans.factory.BeanDefinitionStoreException;
  22. import org.springframework.beans.factory.BeanFactory;
  23. import org.springframework.beans.factory.BeanFactoryAware;
  24. import org.springframework.beans.factory.InitializingBean;
  25. /**
  26. * Base class for dynamic TargetSources that can create new prototype bean
  27. * instances to support a pooling or new-instance-per-invocation strategy.
  28. *
  29. * <p>Such TargetSources must run in a BeanFactory, as it needs to call the
  30. * getBean() method to create a new prototype instance.
  31. *
  32. * @author Rod Johnson
  33. * @version $Id: AbstractPrototypeBasedTargetSource.java,v 1.1 2004/04/20 21:54:01 jhoeller Exp $
  34. * @see org.springframework.beans.factory.BeanFactory#getBean
  35. */
  36. public abstract class AbstractPrototypeBasedTargetSource
  37. implements TargetSource, BeanFactoryAware, InitializingBean {
  38. protected final Log logger = LogFactory.getLog(getClass());
  39. /** Name of the target bean we will create on each invocation */
  40. private String targetBeanName;
  41. /**
  42. * BeanFactory that owns this TargetSource. We need to hold onto this
  43. * reference so that we can create new prototype instances as necessary.
  44. */
  45. private BeanFactory owningBeanFactory;
  46. /** Class of the target */
  47. private Class targetClass;
  48. /**
  49. * Set the name of the target bean in the factory. This bean should be a
  50. * prototype, or the same instance will always be obtained from the
  51. * factory, resulting in the same behavior as the InvokerInterceptor.
  52. * @param targetBeanName name of the target bean in the BeanFactory
  53. * that owns this interceptor
  54. */
  55. public void setTargetBeanName(String targetBeanName) {
  56. this.targetBeanName = targetBeanName;
  57. }
  58. /**
  59. * Return the name of the target bean in the factory.
  60. */
  61. public String getTargetBeanName() {
  62. return this.targetBeanName;
  63. }
  64. /**
  65. * Set the owning BeanFactory. We need to save a reference so that we can
  66. * use the getBean() method on every invocation.
  67. */
  68. public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
  69. this.owningBeanFactory = beanFactory;
  70. if (this.owningBeanFactory.isSingleton(this.targetBeanName)) {
  71. throw new BeanDefinitionStoreException(
  72. "Cannot use PrototypeTargetSource against a Singleton bean; instances would not be independent");
  73. }
  74. logger.info("Getting bean with name '" + this.targetBeanName + "' to find class");
  75. this.targetClass = this.owningBeanFactory.getBean(this.targetBeanName).getClass();
  76. }
  77. /**
  78. * Subclasses should use this method to create a new prototype instance.
  79. */
  80. protected Object newPrototypeInstance() {
  81. if (logger.isInfoEnabled()) {
  82. logger.info("Creating new target from bean '" + this.targetBeanName + "'");
  83. }
  84. return this.owningBeanFactory.getBean(this.targetBeanName);
  85. }
  86. public Class getTargetClass() {
  87. return this.targetClass;
  88. }
  89. public boolean isStatic() {
  90. return false;
  91. }
  92. public void afterPropertiesSet() {
  93. if (this.targetBeanName == null) {
  94. throw new IllegalStateException("targetBeanName is required");
  95. }
  96. }
  97. }