VOOZH about

URL: https://deepwiki.com/hypervel/container/6-aspect-oriented-programming

⇱ Aspect-Oriented Programming | hypervel/container | DeepWiki


Loading...
Menu

Aspect-Oriented Programming

Purpose and Scope

This document provides an introduction to Aspect-Oriented Programming (AOP) support in the Hypervel Container system. It explains the conceptual foundations of AOP, how aspects integrate with the dependency injection container, and the configuration mechanisms for aspect registration.

For detailed documentation on the aspect scanning implementation, see Aspect Scanning. For configuration file loading and merging strategies, see Scan Configuration.

Sources: src/Scanner.php1-73 src/ScanConfig.php1-66


Overview of AOP in Hypervel Container

Aspect-Oriented Programming in Hypervel Container enables cross-cutting concerns to be modularized and applied to services without modifying their core implementation. The AOP system is built on top of Hyperf's annotation-based AOP infrastructure, integrating seamlessly with the container's dependency injection mechanisms.

The AOP implementation consists of two primary components:

ComponentClassPurpose
Aspect ScannerScannerLoads aspect definitions from configuration sources and registers them with AspectCollector
Scan ConfigurationScanConfigAggregates scanning configuration from multiple sources and manages cacheability settings

Both components extend Hyperf's base classes (HyperfScanner and HyperfScanConfig) to provide enhanced configuration loading capabilities, particularly integration with ProviderConfig for package-based aspect registration.

Sources: src/Scanner.php12 src/ScanConfig.php10


Aspect Concepts

What Are Aspects?

Aspects are modular units of cross-cutting functionality that can be applied to multiple classes or methods. Common examples include:

  • Logging: Recording method invocations and parameters
  • Authorization: Checking permissions before method execution
  • Caching: Storing and retrieving method results
  • Transaction Management: Wrapping operations in database transactions
  • Performance Monitoring: Measuring execution time

Aspect Metadata

Each aspect registered in the system contains three types of metadata:

  1. Target Classes: Specific class names to which the aspect applies
  2. Target Annotations: Annotation types that trigger aspect application
  3. Priority: Execution order when multiple aspects apply to the same target (higher values execute first)

Diagram: Aspect Metadata Structure


Sources: src/Scanner.php62-70


Aspect Configuration Sources

Aspects can be defined in three configuration locations, which are merged with specific precedence rules:

Configuration File Hierarchy


Sources: src/Scanner.php24-41

Configuration Format

Aspects can be specified in two formats within configuration files:

FormatExampleDescription
Simple Array[MyAspect::class, AnotherAspect::class]Aspects with default priority
Associative Array[MyAspect::class => 100, AnotherAspect::class => 50]Aspects with explicit priority values

The format is detected at runtime:

If array key is numeric:
 $aspect = $value
 $priority = null (use aspect's default)
Else:
 $aspect = $key
 $priority = (int) $value

Sources: src/Scanner.php49-56


Integration with Hyperf AOP System

The Hypervel Container AOP system delegates to Hyperf's core AOP infrastructure:

Diagram: AOP System Architecture


Sources: src/Scanner.php7-8 src/Scanner.php62-70

Key Integration Points

  1. AspectLoader::load($aspect): Loads aspect metadata by inspecting the aspect class

    • Returns: [$instanceClasses, $instanceAnnotations, $instancePriority]
    • Located at src/Scanner.php62
  2. AspectCollector::setAround(): Registers aspect metadata for use during proxy generation

    • Parameters: aspect class name, target classes, target annotations, priority
    • Located at src/Scanner.php70
  3. AspectCollector::clear($aspect): Removes aspect metadata when aspect is removed from configuration

Sources: src/Scanner.php43-71


Aspect Loading Process

The aspect loading process occurs during container initialization, specifically during the scanning phase:

Diagram: Aspect Loading Sequence


Sources: src/Scanner.php17-72

Change Detection

The scanner implements change detection to avoid re-processing aspects that haven't changed since the last cache modification:

getChangedAspects(aspects, lastCacheModified)
 Returns: [$removed, $changed]
 
$removed: Aspects that were previously cached but are no longer in configuration
$changed: Aspects that are new or have been modified since cache time

This optimization improves performance when aspect scanning cache is enabled.

Sources: src/Scanner.php43


Configuration Directory Discovery

Both Scanner and ScanConfig require a configuration directory to load aspect definitions. The directory is determined by:

  1. ScanConfig::getConfigDir(): Returns the base configuration directory
  2. Path resolution: Specific configuration files are resolved relative to this directory

Configuration File Paths

FilePath PatternPurpose
Aspects$configDir/autoload/aspects.phpPrimary aspect definitions
Base Config$configDir/config.phpBase configuration with aspects array
Dependencies$configDir/dependencies.phpService definitions (loaded by ScanConfig)
Annotations$configDir/annotations.phpAnnotation scanning configuration
App Config$configDir/app.phpApplication-level configuration including scan_cacheable setting

Sources: src/Scanner.php19-27 src/ScanConfig.php22-43


Priority and Execution Order

When multiple aspects apply to the same target (class or method), they execute in priority order:

Priority Rules

  1. Higher priority values execute first (e.g., priority 100 before priority 50)
  2. Priority sources (in precedence order):
    • Configuration file priority (explicit value in aspects array)
    • Aspect class priority (defined within the aspect class itself)
    • Default priority (if neither is specified)

Example Priority Resolution


Sources: src/Scanner.php50-68


AspectCollector Integration

The AspectCollector is a static registry maintained by Hyperf that stores all aspect metadata. The Hypervel Container's Scanner interacts with it through two primary operations:

Registration

AspectCollector::setAround(
 string $aspect, // Aspect class name
 array $classes, // Target class names
 array $annotations, // Target annotation types
 ?int $priority // Execution priority
)

This method stores the aspect metadata for use during proxy generation. When the container resolves a service, Hyperf's proxy generator checks AspectCollector to determine which aspects should be woven into the service's proxy.

Sources: src/Scanner.php70

Removal

AspectCollector::clear(string $aspect)

This method removes all metadata for a specific aspect. It's called when an aspect is removed from configuration files, ensuring that removed aspects don't persist in the collector.

Sources: src/Scanner.php46


Caching and Performance

The scanning system supports caching to improve application bootstrap performance:

Diagram: Caching Strategy


The scan_cacheable setting is typically enabled in production environments:

config/app.php:
 'scan_cacheable' => value($configContent['scan_cacheable'] ?? $environment === 'production')

Sources: src/ScanConfig.php39 src/Scanner.php43


Use Cases

Common Aspect Patterns

Authorization Aspect

Target: Classes or methods with @RequiresPermission annotation
Priority: High (e.g., 100) - execute before business logic
Purpose: Verify user has required permissions before method execution

Caching Aspect

Target: Classes or methods with @Cacheable annotation
Priority: Medium (e.g., 50) - execute after authorization
Purpose: Return cached result if available, otherwise execute and cache

Logging Aspect

Target: All service classes in specific namespaces
Priority: Low (e.g., 10) - execute last to log actual execution
Purpose: Record method invocations, parameters, and results

Transaction Aspect

Target: Classes or methods with @Transactional annotation
Priority: High (e.g., 90) - wrap entire method execution
Purpose: Begin transaction before method, commit on success, rollback on exception

Summary

The Hypervel Container's AOP system provides:

  • Configuration Flexibility: Three configuration sources (ProviderConfig, config.php, aspects.php) with clear precedence rules
  • Priority Control: Fine-grained control over aspect execution order through explicit priority values
  • Change Detection: Incremental loading of only changed aspects when caching is enabled
  • Hyperf Integration: Seamless integration with Hyperf's AspectCollector and proxy generation system
  • Package Support: First-class support for package-provided aspects through ProviderConfig

For implementation details of the scanning process, see Aspect Scanning. For configuration loading mechanics, see Scan Configuration.

Sources: src/Scanner.php1-73 src/ScanConfig.php1-66