Aspectran’s IoC/DI container supports a comprehensive Bean Scopes architecture that governs the instantiation timing, lifecycle boundaries, and memory residency of managed Bean components.
Scopes define whether a component is shared globally across the entire application (Singleton), instantiated freshly upon every retrieval (Prototype), or strictly isolated to a single HTTP/CLI request (Request) or user session (Session).
Aspectran provides four standard scopes defined in the ScopeType enumeration. Internally, the framework drives a sophisticated lifecycle pipeline through dedicated scope strategy contracts (Scope and AbstractScope), delivering thread safety, reverse-order destruction, lazy destruction (lazy-destroy), and distributed session clustering support.
1. Scope Architecture Class Diagram
Aspectran’s scope subsystem employs the Strategy Pattern to abstract instance caching and destruction lifecycles uniformly across runtime environments.
classDiagram
direction TB
class Scope {
<<interface>>
+getScopeType() ScopeType
+getScopeLock() ReadWriteLock
+getBeanInstance(BeanRule) BeanInstance
+putBeanInstance(BeanRule, BeanInstance)
+destroy(Object)
+destroy()
}
class NonPersistent {
<<interface>>
}
class AbstractScope {
<<abstract>>
-Map~BeanRule, BeanInstance~ scopedBeanInstances
+destroy()
#doDestroy(BeanRule, BeanInstance)
}
class SingletonScope {
-ReadWriteLock scopeLock
+getScopeType() ScopeType.SINGLETON
}
class RequestScope {
+getScopeType() ScopeType.REQUEST
}
class SessionScope {
-ReadWriteLock scopeLock
+getScopeType() ScopeType.SESSION
+valueUnbound(Session, String, Object)
-findMatchingBeanRule(BeanRule) BeanRule
}
class SessionBindingListener {
<<interface>>
+valueBound(Session, String, Object)
+valueUnbound(Session, String, Object)
}
NonPersistent <|-- Scope
Scope <|.. AbstractScope
AbstractScope <|-- SingletonScope
AbstractScope <|-- RequestScope
AbstractScope <|-- SessionScope
SessionBindingListener <|.. SessionScope
2. In-Depth Analysis of 4 Standard Bean Scopes
Aspectran provides four distinct scopes tailored to component responsibilities and concurrency requirements.
1) SINGLETON (SingletonScope)
- Lifecycle and Visibility:
- Exactly one shared instance is created within the
ActivityContextand reused application-wide. - Pre-instantiated (eager initialization) during container startup (
initialize()), or deferred until first access if configured withlazy-init="true".
- Exactly one shared instance is created within the
- Concurrency and Thread Safety:
- Incorporates an internal
ReentrantReadWriteLockto thread-safely coordinate concurrent access.
- Incorporates an internal
- Ideal Use Cases:
- Stateless service classes, DAOs, repositories, utility classes, and factory components.
- Operational Cautions:
- Because singleton instances are accessed concurrently by multiple threads, they must avoid mutable instance state. Mutable fields require explicit synchronization.
2) PROTOTYPE
- Lifecycle and Visibility:
- Creates a brand-new independent instance every time the bean is looked up (via injection or
getBean()).
- Creates a brand-new independent instance every time the bean is looked up (via injection or
- Container Non-Managed Characteristics:
- The container participates only through instantiation, dependency injection, and initial callbacks (
@Initialize). - Created instances are not cached within any scope registry; ownership transfers entirely to client code, and subsequent memory reclamation is handled exclusively by the JVM Garbage Collector (GC).
- Therefore, destruction callbacks (
@Destroy,DisposableBean.destroy()) on prototype beans are never invoked by the container.
- The container participates only through instantiation, dependency injection, and initial callbacks (
- Ideal Use Cases:
- Stateful components that cannot be shared across threads, dynamic calculation models, or short-lived batch tasks.
3) REQUEST (RequestScope)
- Lifecycle and Visibility:
- Valid strictly within the lifecycle of a single request (
Activity). - Repeated lookups within the same request return the identical instance, while concurrent client requests receive isolated instances.
- Valid strictly within the lifecycle of a single request (
- Environment Binding Mechanism:
- Stored inside the internal attribute registry of the environment’s
RequestAdapter. - When request handling finishes and
Activity.finish()is called,RequestScope.destroy()triggers sequentially, invoking destruction callbacks on all request-scoped beans and clearing memory.
- Stored inside the internal attribute registry of the environment’s
- Environmental Constraints:
- Requires runtime environments supporting
RequestAdapter(Web:ServletWebActivity,NettyActivity,TowActivity; CLI:ShellActivity). Invoking in unsupported environments raises anUnsupportedBeanScopeException.
- Requires runtime environments supporting
- Ideal Use Cases:
- Request audit tokens, distributed trace IDs, and form command binding objects.
4) SESSION (SessionScope)
- Lifecycle and Visibility:
- Valid throughout the lifetime of a single user session. Successive requests from the same authenticated user share the same instance.
- Session Lifecycle Binding (
SessionBindingListener):- When a session is invalidated or expires due to timeout, the
valueUnbound()callback is triggered, executing destruction callbacks on all session-scoped beans stored in the session.
- When a session is invalidated or expires due to timeout, the
- Distributed Clustering Support (
findMatchingBeanRule):- In clustered multi-node environments where sessions are serialized and replicated across different JVMs, memory hash addresses change.
SessionScopeincorporates cluster-aware matching logic that re-binds deserialized instances against localBeanRuledefinitions by bean ID or class name.
- In clustered multi-node environments where sessions are serialized and replicated across different JVMs, memory hash addresses change.
- Serialization Defense (
NonPersistent):- Implements marker contract
NonPersistentto prevent framework scope metadata from being needlessly dumped into external persistence stores (Redis, session databases) when sessions are replicated.
- Implements marker contract
- Ideal Use Cases:
- User authentication credentials, shopping carts, and personalized UI preference state.
3. Two-Phase Reverse Destruction Pipeline in AbstractScope
AbstractScope executes a disciplined Two-Phase Reverse Destruction pipeline to prevent dependency breakage and guarantee safe resource closure during teardown.
sequenceDiagram
autonumber
participant Container as Scope.destroy()
participant General as General Beans (Non-Lazy)
participant Lazy as Lazy Destruction Beans (lazy-destroy="true")
Note over Container: Phase 1: Destroy general beans in "Reverse Creation Order"
Container->>General: destroyScopedBean(Bean N)
Container->>General: destroyScopedBean(Bean N-1)
Container->>General: destroyScopedBean(Bean 1)
Note over General: Business services, controllers, DAOs cleanly closed
Note over Container: Phase 2: Final destruction of lazy-destroy beans
Container->>Lazy: destroyScopedBean(LazyBean 2)
Container->>Lazy: destroyScopedBean(LazyBean 1)
Note over Lazy: Database connection pools, thread pools safely released
1) Reverse Creation Order Principle
- If Bean A depends on Bean B, Bean B is instantiated first and Bean A second.
- During destruction, Bean A (the dependent) must be cleaned up before Bean B (the dependency) is closed.
AbstractScopetraverses its registered instance list (scopedBeanInstances) in reverse order usingListIterator.previous().
2) Lazy Destruction Property (lazy-destroy="true")
- Critical infrastructure resources—such as database connection pools (HikariCP), network sockets, and asynchronous thread pools—must remain operational until all business beans have completely shut down.
- Beans marked with
lazy-destroy="true"are excluded from Phase 1 destruction and staged in a deferred queue, executing their shutdown hooks only in Phase 2 after all standard beans are destroyed.
3) Safe Teardown of Factory-Style Beans
- For product beans generated via factory beans (
factory):- Invokes the product bean’s own
destroyMethodandDisposableBean.destroy(). - Invokes the factory bean’s own
destroyMethodandDisposableBean.destroy(). - Guarantees that callbacks across both layers execute without omission.
- Invokes the product bean’s own
4. Declarative Scope Configuration Syntax
Aspectran supports identical scope declarations across XML, APON, and Java annotations.
XML Configuration
<!-- Singleton Bean (Default) -->
<bean id="orderService" class="com.example.OrderServiceImpl" scope="singleton"/>
<!-- Prototype Bean -->
<bean id="reportTask" class="com.example.ReportTask" scope="prototype"/>
<!-- Request-Scoped Bean with Lazy Destruction -->
<bean id="requestContext" class="com.example.RequestContext" scope="request" lazy-destroy="true"/>
<!-- Session-Scoped Bean -->
<bean id="userCart" class="com.example.UserCart" scope="session"/>
APON Configuration
bean: {
id: userCart
class: com.example.UserCart
scope: session
}
Java Annotations
@Component
@Scope(ScopeType.PROTOTYPE)
public class ReportTask {
// ...
}
@Component
@Scope("session")
public class UserCart {
// ...
}
5. Comprehensive Comparison Matrix: 4 Bean Scopes
| Scope | Underlying Strategy Class | Instance Sharing Boundary | Thread Safety | Container Teardown Management | Ideal Use Cases | Environmental Constraints |
|---|---|---|---|---|---|---|
SINGLETON | SingletonScope | Entire ActivityContext | High (ReadWriteLock) | Fully Managed (Context shutdown) | Stateless services, DAOs, configuration beans | None |
PROTOTYPE | None (Returned immediately) | Not shared (Created on every lookup) | Independent (No sharing) | Unmanaged (Collected by GC, no destroy callback) | Stateful computing tasks, short-lived jobs | None |
REQUEST | RequestScope | Single request (Activity) | Single-thread isolation | Fully Managed (Request completion) | Request tracers, form command binding objects | Requires RequestAdapter |
SESSION | SessionScope | Single user session | High (ReadWriteLock) | Fully Managed (Session unbind / invalidation) | Login credentials, shopping carts, user preferences | Requires SessionAdapter |
🔍 Related Detailed Mechanisms
- For the overarching IoC container model that manages bean registrations and lifecycles, see ActivityContext: The Heart of the Aspectran Container.
- For proxy interception mechanisms applied to scoped beans, see Aspectran AOP Proxy Mechanism.
- For how request and session scopes bind into runtime adapters, see Aspectran Adapter Architecture.
6. Next Steps: Exploring Detailed Mechanisms
To examine how Aspectran isolates resources and loads application classes dynamically, proceed to the Aspectran ClassLoader Architecture guide.
To inspect how all mechanisms and packages interconnect across the entire framework, refer to the Aspectran Detailed Mechanisms Index.