KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > aop > target > AbstractBeanFactoryBasedTargetSource


1 /*
2  * Copyright 2002-2007 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
17 package org.springframework.aop.target;
18
19 import java.io.NotSerializableException JavaDoc;
20 import java.io.ObjectStreamException JavaDoc;
21 import java.io.Serializable JavaDoc;
22
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25
26 import org.springframework.aop.TargetSource;
27 import org.springframework.beans.BeansException;
28 import org.springframework.beans.factory.BeanFactory;
29 import org.springframework.beans.factory.BeanFactoryAware;
30 import org.springframework.util.ClassUtils;
31 import org.springframework.util.ObjectUtils;
32
33 /**
34  * Base class for {@link org.springframework.aop.TargetSource} implementations
35  * that are based on a Spring {@link org.springframework.beans.factory.BeanFactory},
36  * delegating to Spring-managed bean instances.
37  *
38  * <p>Subclasses can create prototype instances or lazily access a
39  * singleton target, for example. See {@link LazyInitTargetSource} and
40  * {@link AbstractPrototypeBasedTargetSource}'s subclasses for concrete strategies.
41  *
42  * <p>BeanFactory-based TargetSources are serializable. This involves
43  * disconnecting the current target and turning into a {@link SingletonTargetSource}.
44  *
45  * @author Juergen Hoeller
46  * @author Rod Johnson
47  * @since 1.1.4
48  * @see org.springframework.beans.factory.BeanFactory#getBean
49  * @see LazyInitTargetSource
50  * @see PrototypeTargetSource
51  * @see ThreadLocalTargetSource
52  * @see CommonsPoolTargetSource
53  */

54 public abstract class AbstractBeanFactoryBasedTargetSource
55         implements TargetSource, BeanFactoryAware, Serializable JavaDoc {
56
57     /** use serialVersionUID from Spring 1.2.7 for interoperability */
58     private static final long serialVersionUID = -4721607536018568393L;
59
60
61     /** Logger available to subclasses */
62     protected final Log logger = LogFactory.getLog(getClass());
63
64     /** Name of the target bean we will create on each invocation */
65     private String JavaDoc targetBeanName;
66
67     /** Class of the target */
68     private Class JavaDoc targetClass;
69
70     /**
71      * BeanFactory that owns this TargetSource. We need to hold onto this
72      * reference so that we can create new prototype instances as necessary.
73      */

74     private BeanFactory beanFactory;
75
76
77     /**
78      * Set the name of the target bean in the factory.
79      * <p>The target bean should not be a singleton, else the same instance will
80      * always be obtained from the factory, resulting in the same behavior as
81      * provided by {@link SingletonTargetSource}.
82      * @param targetBeanName name of the target bean in the BeanFactory
83      * that owns this interceptor
84      * @see SingletonTargetSource
85      */

86     public void setTargetBeanName(String JavaDoc targetBeanName) {
87         this.targetBeanName = targetBeanName;
88     }
89
90     /**
91      * Return the name of the target bean in the factory.
92      */

93     public String JavaDoc getTargetBeanName() {
94         return this.targetBeanName;
95     }
96
97     /**
98      * Specify the target class explicitly, to avoid any kind of access to the
99      * target bean (for example, to avoid initialization of a FactoryBean instance).
100      * <p>Default is to detect the type automatically, through a <code>getType</code>
101      * call on the BeanFactory (or even a full <code>getBean</code> call as fallback).
102      */

103     public void setTargetClass(Class JavaDoc targetClass) {
104         this.targetClass = targetClass;
105     }
106
107     /**
108      * Set the owning BeanFactory. We need to save a reference so that we can
109      * use the <code>getBean</code> method on every invocation.
110      */

111     public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
112         if (this.targetBeanName == null) {
113             throw new IllegalStateException JavaDoc("Property'targetBeanName' is required");
114         }
115         this.beanFactory = beanFactory;
116     }
117
118     /**
119      * Return the owning BeanFactory.
120      */

121     public BeanFactory getBeanFactory() {
122         return this.beanFactory;
123     }
124
125
126     public synchronized Class JavaDoc getTargetClass() {
127         if (this.targetClass == null && this.beanFactory != null) {
128             // Determine type of the target bean.
129
this.targetClass = this.beanFactory.getType(this.targetBeanName);
130             if (this.targetClass == null) {
131                 if (logger.isTraceEnabled()) {
132                     logger.trace("Getting bean with name '" + this.targetBeanName + "' in order to determine type");
133                 }
134                 this.targetClass = this.beanFactory.getBean(this.targetBeanName).getClass();
135             }
136         }
137         return this.targetClass;
138     }
139
140     public boolean isStatic() {
141         return false;
142     }
143
144     public void releaseTarget(Object JavaDoc target) throws Exception JavaDoc {
145         // Nothing to do here.
146
}
147
148
149     /**
150      * Copy configuration from the other AbstractBeanFactoryBasedTargetSource object.
151      * Subclasses should override this if they wish to expose it.
152      * @param other object to copy configuration from
153      */

154     protected void copyFrom(AbstractBeanFactoryBasedTargetSource other) {
155         this.targetBeanName = other.targetBeanName;
156         this.targetClass = other.targetClass;
157         this.beanFactory = other.beanFactory;
158     }
159
160     /**
161      * Replaces this object with a SingletonTargetSource on serialization.
162      * Protected as otherwise it won't be invoked for subclasses.
163      * (The <code>writeReplace()</code> method must be visible to the class
164      * being serialized.)
165      * <p>With this implementation of this method, there is no need to mark
166      * non-serializable fields in this class or subclasses as transient.
167      */

168     protected Object JavaDoc writeReplace() throws ObjectStreamException JavaDoc {
169         if (logger.isDebugEnabled()) {
170             logger.debug("Disconnecting TargetSource [" + this + "]");
171         }
172         try {
173             // Create disconnected SingletonTargetSource.
174
return new SingletonTargetSource(getTarget());
175         }
176         catch (Exception JavaDoc ex) {
177             logger.error("Cannot get target for disconnecting TargetSource [" + this + "]", ex);
178             throw new NotSerializableException JavaDoc(
179                     "Cannot get target for disconnecting TargetSource [" + this + "]: " + ex);
180         }
181     }
182
183
184     public boolean equals(Object JavaDoc other) {
185         if (this == other) {
186             return true;
187         }
188         if (other == null || !getClass().equals(other.getClass())) {
189             return false;
190         }
191         AbstractBeanFactoryBasedTargetSource otherTargetSource = (AbstractBeanFactoryBasedTargetSource) other;
192         return (ObjectUtils.nullSafeEquals(this.beanFactory, otherTargetSource.beanFactory) &&
193                 ObjectUtils.nullSafeEquals(this.targetBeanName, otherTargetSource.targetBeanName));
194     }
195
196     public int hashCode() {
197         int hashCode = getClass().hashCode();
198         hashCode = 13 * hashCode + ObjectUtils.nullSafeHashCode(this.beanFactory);
199         hashCode = 13 * hashCode + ObjectUtils.nullSafeHashCode(this.targetBeanName);
200         return hashCode;
201     }
202
203     public String JavaDoc toString() {
204         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
205         sb.append(ClassUtils.getShortName(getClass()));
206         sb.append(" for target bean '").append(this.targetBeanName).append("'");
207         if (this.targetClass != null) {
208             sb.append(" of type [").append(this.targetClass.getName()).append("]");
209         }
210         return sb.toString();
211     }
212
213 }
214
Popular Tags