001: /*
002: * Copyright 2002-2007 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.aop.target;
018:
019: import org.apache.commons.logging.Log;
020: import org.apache.commons.logging.LogFactory;
021:
022: import org.springframework.aop.TargetSource;
023:
024: /**
025: * {@link org.springframework.aop.TargetSource} implementation that will
026: * lazily create a user-managed object.
027: *
028: * <p>Creation of the lazy target object is controlled by the user by implementing
029: * the {@link #createObject()} method. This <code>TargetSource</code> will invoke
030: * this method the first time the proxy is accessed.
031: *
032: * <p>Useful when you need to pass a reference to some dependency to an object
033: * but you don't actually want the dependency to be created until it is first used.
034: * A typical scenario for this is a connection to a remote resource.
035: *
036: * @author Rob Harrop
037: * @author Juergen Hoeller
038: * @since 1.2.4
039: * @see #isInitialized()
040: * @see #createObject()
041: */
042: public abstract class AbstractLazyCreationTargetSource implements
043: TargetSource {
044:
045: /** Logger available to subclasses */
046: protected final Log logger = LogFactory.getLog(getClass());
047:
048: /** The lazily initialized target object */
049: private Object lazyTarget;
050:
051: /**
052: * Return whether the lazy target object of this TargetSource
053: * has already been fetched.
054: */
055: public synchronized boolean isInitialized() {
056: return (this .lazyTarget != null);
057: }
058:
059: /**
060: * This default implementation returns <code>null</code> if the
061: * target is <code>null</code> (it is hasn't yet been initialized),
062: * or the target class if the target has already been initialized.
063: * <p>Subclasses may wish to override this method in order to provide
064: * a meaningful value when the target is still <code>null</code>.
065: * @see #isInitialized()
066: */
067: public synchronized Class getTargetClass() {
068: return (this .lazyTarget != null ? this .lazyTarget.getClass()
069: : null);
070: }
071:
072: public boolean isStatic() {
073: return false;
074: }
075:
076: /**
077: * Returns the lazy-initialized target object,
078: * creating it on-the-fly if it doesn't exist already.
079: * @see #createObject()
080: */
081: public synchronized Object getTarget() throws Exception {
082: if (this .lazyTarget == null) {
083: logger.debug("Initializing lazy target object");
084: this .lazyTarget = createObject();
085: }
086: return this .lazyTarget;
087: }
088:
089: public void releaseTarget(Object target) throws Exception {
090: // nothing to do
091: }
092:
093: /**
094: * Subclasses should implement this method to return the lazy initialized object.
095: * Called the first time the proxy is invoked.
096: * @return the created object
097: * @throws Exception if creation failed
098: */
099: protected abstract Object createObject() throws Exception;
100:
101: }
|