# How to Implement Hot Reload with Async and Sync Modes in OWNER API

> Implement hot reload in OWNER API with SYNC or ASYNC modes for dynamic configuration updates. Easily monitor changes on method invocation or background threads. Boost your development.

- Repository: [Matteo Baccan/owner](https://github.com/matteobaccan/owner)
- Tags: how-to-guide
- Published: 2026-03-07

---

**Use the `@HotReload` annotation with `type = HotReloadType.SYNC` (default) to check for configuration changes on every method invocation, or `type = HotReloadType.ASYNC` to spawn a background thread that monitors files at a fixed interval.**

The OWNER API is a Java configuration library that maps property files to type-safe interfaces. Implementing **hot reload with async and sync modes in OWNER API** allows applications to detect file changes automatically without restarting the JVM, choosing between on-demand checks or continuous background monitoring based on your latency requirements.

## Understanding Hot Reload Modes

OWNER provides two distinct strategies for detecting external configuration changes. The mode determines when the library interrogates the underlying `WatchableResource` instances (files or system properties) and triggers a reload.

### Synchronous Mode (Default)

In **Synchronous** mode (`HotReloadType.SYNC`), the library checks for modifications every time you invoke a method on the configuration proxy. According to the source code in [`PropertiesInvocationHandler.java`](https://github.com/matteobaccan/owner/blob/main/PropertiesInvocationHandler.java) (lines 57‑60), the `invoke()` method automatically delegates to `propertiesManager.syncReloadCheck()` before processing the property lookup.

This means every call to `cfg.someProperty()` triggers `PropertiesManager.syncReloadCheck()` (lines 357‑360), which asks `HotReloadLogic.isSync()` and `HotReloadLogic.checkAndReload()` to verify if the underlying files have changed.

### Asynchronous Mode

In **Asynchronous** mode (`HotReloadType.ASYNC`), OWNER delegates monitoring to a background thread. During `PropertiesManager` construction (lines 118‑125), the code inspects `hotReloadLogic.isAsync()` and schedules a `ScheduledExecutorService` task:

```java
scheduler.scheduleAtFixedRate(
    () -> hotReloadLogic.checkAndReload(),
    hotReload.value(),
    hotReload.value(),
    hotReload.unit());

```

This task runs independently of your application code, checking resources at the interval specified by the `@HotReload` annotation even when the configuration object sits idle.

## Core Components

Four primary classes collaborate to implement hot reload capabilities.

### @HotReload Annotation

The `@HotReload` annotation (defined in [`Config.java`](https://github.com/matteobaccan/owner/blob/main/Config.java), lines 205‑246) declares the monitoring interval (`value` and `unit`) and the reload strategy (`type`). It attaches to your configuration interface and is read during proxy instantiation by `PropertiesManager`.

```java
@Retention(RUNTIME)
@Target(TYPE)
public @interface HotReload {
    int value() default 5;
    TimeUnit unit() default TimeUnit.SECONDS;
    HotReloadType type() default HotReloadType.SYNC;
}

```

### HotReloadLogic

`HotReloadLogic` (lines 25‑130 in [`HotReloadLogic.java`](https://github.com/matteobaccan/owner/blob/main/HotReloadLogic.java)) encapsulates the watch list and reload decision logic. It maintains a collection of `WatchableResource` objects and exposes two critical methods:

- **`checkAndReload()`**: Called either by the synchronous path or the async scheduler to trigger a reload when necessary.
- **`needsReload()`**: Compares the current timestamp against the last check time and interrogates each registered resource via `isChanged()`.

### PropertiesManager

`PropertiesManager` owns the runtime state and the `HotReloadLogic` instance. When the `@HotReload` annotation is present, the constructor (lines 108‑129) initializes the logic and, for async mode, schedules the background task. It also provides `syncReloadCheck()` (lines 357‑360) as the entry point for synchronous verification.

### PropertiesInvocationHandler

Every configuration proxy routes method calls through `PropertiesInvocationHandler.invoke()` (lines 57‑60). This handler guarantees that synchronous reload checks execute before property resolution, ensuring the configuration is fresh on every access when using `SYNC` mode.

## Implementation Examples

### Synchronous Hot Reload

Synchronous mode requires no explicit setup beyond the annotation. Every method call implicitly checks for file changes.

```java
import org.aeonbits.owner.Config;
import org.aeonbits.owner.ConfigFactory;
import org.aeonbits.owner.Config.HotReload;
import org.aeonbits.owner.Config.Sources;

@Sources("file:conf/app.properties")
@HotReload(2)  // checks every 2 seconds, SYNC is implicit
interface AppConfig extends Config {
    @DefaultValue("8080")
    int port();
    
    String dbUrl();
}

// Usage
AppConfig cfg = ConfigFactory.create(AppConfig.class);
System.out.println(cfg.port());  // triggers syncReloadCheck() first

```

*Each invocation of `cfg.port()` forces `PropertiesInvocationHandler` to call `propertiesManager.syncReloadCheck()`, which delegates to `HotReloadLogic.checkAndReload()` if the configured interval has elapsed.*

### Asynchronous Hot Reload

Asynchronous mode decouples monitoring from application logic, ideal for high-throughput scenarios where you cannot tolerate the latency of file system checks on every property access.

```java
import org.aeonbits.owner.Config;
import org.aeonbits.owner.ConfigFactory;
import org.aeonbits.owner.Config.HotReload;
import org.aeonbits.owner.Config.HotReloadType;
import org.aeonbits.owner.Config.Sources;
import org.aeonbits.owner.Reloadable;
import java.util.concurrent.TimeUnit;

@Sources("file:conf/app.properties")
@HotReload(value = 5, unit = TimeUnit.SECONDS, type = HotReloadType.ASYNC)
interface AsyncAppConfig extends Config, Reloadable {
    String dbUrl();
}

// Usage
AsyncAppConfig cfg = ConfigFactory.create(AsyncAppConfig.class);
cfg.addReloadListener(event -> 
    System.out.println("Configuration reloaded at " + event.getTime()));
// Background thread checks the file every 5 seconds automatically

```

*The `PropertiesManager` constructor schedules a `ScheduledExecutorService` task (lines 118‑125) that invokes `hotReloadLogic.checkAndReload()` at the specified interval, regardless of whether the application calls configuration methods.*

### Listening to Reload Events

To react to configuration updates, implement the `Reloadable` interface and register listeners. The `PropertiesManager.reload()` method fires `ReloadEvent` instances to all registered listeners after the internal `Properties` map is replaced.

```java
cfg.addReloadListener(event -> {
    System.out.println("Reload detected: " + event.getTime());
    // Re-initialize dependent services here
});

```

## How It Works Under the Hood

The reload lifecycle follows a deterministic sequence implemented in `matteobaccan/owner`:

1. **Annotation Detection**: `ConfigFactory.create()` builds the proxy and `PropertiesManager` extracts the `@HotReload` annotation from the interface hierarchy.
2. **Resource Registration**: `HotReloadLogic` receives the URI list from `@Sources` and instantiates `WatchableFile` instances for physical files or `WatchableSystemProperties` for `system:properties`.
3. **Path Selection**:
   - **SYNC**: No background thread is created. `PropertiesInvocationHandler.invoke()` routes every call through `syncReloadCheck()` → `HotReloadLogic.checkAndReload()`.
   - **ASYNC**: `PropertiesManager` schedules a periodic task via `scheduler.scheduleAtFixedRate()` that runs `checkAndReload()` independently.
4. **Change Detection**: `HotReloadLogic.needsReload()` verifies the interval timeout and polls each `WatchableResource.isChanged()`.
5. **Atomic Reload**: When changes are detected, `HotReloadLogic.checkAndReload()` invokes `PropertiesManager.reload()`, which loads new properties, updates the internal state, and fires `ReloadEvent` notifications.

## Summary

- **Synchronous mode** (`HotReloadType.SYNC`) checks for file changes on every proxy method call via `PropertiesInvocationHandler.invoke()` and `PropertiesManager.syncReloadCheck()`.
- **Asynchronous mode** (`HotReloadType.ASYNC`) spawns a `ScheduledExecutorService` thread in `PropertiesManager` (lines 118‑125) to monitor files at a fixed interval.
- Use the `@HotReload` annotation (defined in [`Config.java`](https://github.com/matteobaccan/owner/blob/main/Config.java) lines 205‑246) to configure the interval and mode.
- Implement `Reloadable` and add listeners to receive `ReloadEvent` notifications when the configuration updates.
- The core logic resides in [`HotReloadLogic.java`](https://github.com/matteobaccan/owner/blob/main/HotReloadLogic.java) (lines 25‑130), which manages the watch list and reload decisions.

## Frequently Asked Questions

### How do I enable hot reload in OWNER API without blocking my application threads?

Use **asynchronous mode** by setting `type = HotReloadType.ASYNC` in the `@HotReload` annotation. According to the source code in [`PropertiesManager.java`](https://github.com/matteobaccan/owner/blob/main/PropertiesManager.java) (lines 118‑125), this schedules a background `ScheduledExecutorService` task that checks files periodically without interfering with your main execution path.

### What is the default hot reload behavior if I only specify the interval?

The default type is **Synchronous** (`HotReloadType.SYNC`). If you omit the `type` attribute, OWNER checks for configuration changes every time you access a property method, as implemented in `PropertiesInvocationHandler.invoke()` (lines 57‑60).

### Can I receive notifications when OWNER reloads the configuration?

Yes. Have your configuration interface extend `Reloadable` and call `addReloadListener()`. The listener receives a `ReloadEvent` after `PropertiesManager.reload()` completes and the internal properties map is updated, allowing you to refresh dependent application state.

### How does OWNER determine if a property file has changed?

`HotReloadLogic.needsReload()` (defined in [`HotReloadLogic.java`](https://github.com/matteobaccan/owner/blob/main/HotReloadLogic.java) lines 25‑130) tracks the last check timestamp and interrogates each registered `WatchableResource` (files or system properties) via `isChanged()`. Only if the interval has elapsed and a resource reports modification does the library trigger `PropertiesManager.reload()`.