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.beans.factory.config;
018:
019: import org.springframework.beans.factory.ObjectFactory;
020:
021: /**
022: * Strategy interface used by a {@link ConfigurableBeanFactory},
023: * representing a target scope to hold bean instances in.
024: * This allows for extending the BeanFactory's standard scopes
025: * {@link ConfigurableBeanFactory#SCOPE_SINGLETON "singleton"} and
026: * {@link ConfigurableBeanFactory#SCOPE_PROTOTYPE "prototype"}
027: * with custom further scopes, registered for a
028: * {@link ConfigurableBeanFactory#registerScope(String, Scope) specific key}.
029: *
030: * <p>{@link org.springframework.context.ApplicationContext} implementations
031: * such as a {@link org.springframework.web.context.WebApplicationContext}
032: * may register additional standard scopes specific to their environment,
033: * e.g. {@link org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST "request"}
034: * and {@link org.springframework.web.context.WebApplicationContext#SCOPE_SESSION "session"},
035: * based on this Scope SPI.
036: *
037: * <p>Even if its primary use is for extended scopes in a web environment,
038: * this SPI is completely generic: It provides the ability to get and put
039: * objects from any underlying storage mechanism, such as an HTTP session
040: * or a custom conversation mechanism. The name passed into this class's
041: * <code>get</code> and <code>remove</code> methods will identify the
042: * target object in the current scope.
043: *
044: * <p><code>Scope</code> implementations are expected to be thread-safe.
045: * One <code>Scope</code> instance can be used with multiple bean factories
046: * at the same time, if desired (unless it explicitly wants to be aware of
047: * the containing BeanFactory), with any number of threads accessing
048: * the <code>Scope</code> concurrently from any number of factories.
049: *
050: * @author Juergen Hoeller
051: * @author Rob Harrop
052: * @since 2.0
053: * @see ConfigurableBeanFactory#registerScope
054: * @see CustomScopeConfigurer
055: * @see org.springframework.aop.scope.ScopedProxyFactoryBean
056: * @see org.springframework.web.context.request.RequestScope
057: * @see org.springframework.web.context.request.SessionScope
058: */
059: public interface Scope {
060:
061: /**
062: * Return the object with the given name from the underlying scope,
063: * {@link org.springframework.beans.factory.ObjectFactory#getObject() creating it}
064: * if not found in the underlying storage mechanism.
065: * <p>This is the central operation of a Scope, and the only operation
066: * that is absolutely required.
067: * @param name the name of the object to retrieve
068: * @param objectFactory the {@link ObjectFactory} to use to create the scoped
069: * object if it is not present in the underlying storage mechanism
070: * @return the desired object (never <code>null</code>)
071: */
072: Object get(String name, ObjectFactory objectFactory);
073:
074: /**
075: * Remove the object with the given <code>name</code> from the underlying scope.
076: * <p>Returns <code>null</code> if no object was found; otherwise
077: * returns the removed <code>Object</code>.
078: * <p>Note that an implementation should also remove a registered destruction
079: * callback for the specified object, if any. It does, however, <i>not</i>
080: * need to <i>execute</i> a registered destruction callback in this case,
081: * since the object will be destroyed by the caller (if appropriate).
082: * <p><b>Note: This is an optional operation.</b> Implementations may throw
083: * {@link UnsupportedOperationException} if they do not support explicitly
084: * removing an object.
085: * @param name the name of the object to remove
086: * @return the removed object, or <code>null</code> if no object was present
087: * @see #registerDestructionCallback
088: */
089: Object remove(String name);
090:
091: /**
092: * Register a callback to be executed on destruction of the specified
093: * object in the scope (or at destruction of the entire scope, if the
094: * scope does not destroy individual objects but rather only terminates
095: * in its entirety).
096: * <p><b>Note: This is an optional operation.</b> This method will only
097: * be called for scoped beans with actual destruction configuration
098: * (DisposableBean, destroy-method, DestructionAwareBeanPostProcessor).
099: * Implementations should do their best to execute a given callback
100: * at the appropriate time. If such a callback is not supported by the
101: * underlying runtime environment at all, the callback <i>must be
102: * ignored and a corresponding warning should be logged</i>.
103: * <p>Note that 'destruction' refers to to automatic destruction of
104: * the object as part of the scope's own lifecycle, not to the individual
105: * scoped object having been explicitly removed by the application.
106: * If a scoped object gets removed via this facade's {@link #remove(String)}
107: * method, any registered destruction callback should be removed as well,
108: * assuming that the removed object will be reused or manually destroyed.
109: * @param name the name of the object to execute the destruction callback for
110: * @param callback the destruction callback to be executed.
111: * Note that the passed-in Runnable will never throw an exception,
112: * so it can safely be executed without an enclosing try-catch block.
113: * Furthermore, the Runnable will usually be serializable, provided
114: * that its target object is serializable as well.
115: * @see org.springframework.beans.factory.DisposableBean
116: * @see org.springframework.beans.factory.support.AbstractBeanDefinition#getDestroyMethodName()
117: * @see DestructionAwareBeanPostProcessor
118: */
119: void registerDestructionCallback(String name, Runnable callback);
120:
121: /**
122: * Return the <em>conversation ID</em> for the current underlying scope, if any.
123: * <p>The exact meaning of the conversation ID depends on the underlying
124: * storage mechanism. In the case of session-scoped objects, the
125: * conversation ID would typically be equal to (or derived from) the
126: * {@link javax.servlet.http.HttpSession#getId() session ID}; in the
127: * case of a custom conversation that sits within the overall session,
128: * the specific ID for the current conversation would be appropriate.
129: * <p><b>Note: This is an optional operation.</b> It is perfectly valid to
130: * return <code>null</code> in an implementation of this method if the
131: * underlying storage mechanism has no obvious candidate for such an ID.
132: * @return the conversation ID, or <code>null</code> if there is no
133: * conversation ID for the current scope
134: */
135: String getConversationId();
136:
137: }
|