# How to Listen to Reload Events Using the ReloadListener Interface in Owner

> Learn to listen for reload events in Owner using the ReloadListener interface. Implement and register the listener to get callbacks after configuration reloads.

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

---

**Implement the `org.aeonbits.owner.event.ReloadListener` interface and register it via `addReloadListener()` on your configuration instance to receive callbacks after each successful reload.**

The Owner configuration library (matteobaccan/owner) provides a robust event system that notifies your application when configuration properties change. By leveraging the **ReloadListener interface**, you can execute custom logic—such as refreshing caches, logging changes, or triggering notifications—immediately after a reload completes.

## Understanding the ReloadListener Interface

The `ReloadListener` interface, defined in [`owner/src/main/java/org/aeonbits/owner/event/ReloadListener.java`](https://github.com/matteobaccan/owner/blob/main/owner/src/main/java/org/aeonbits/owner/event/ReloadListener.java), declares a single callback method:

```java
void reloadPerformed(ReloadEvent event);

```

Owner invokes this method **after** the properties have been successfully reloaded, ensuring that any logic inside `reloadPerformed` can safely read updated values from the configuration object. The `ReloadEvent` parameter, implemented in [`owner/src/main/java/org/aeonbits/owner/event/ReloadEvent.java`](https://github.com/matteobaccan/owner/blob/main/owner/src/main/java/org/aeonbits/owner/event/ReloadEvent.java), provides metadata about the reload operation, including the source configuration instance and the timestamp of the event.

## Registering a ReloadListener

To begin listening for reload events, create an instance of `ReloadListener` and register it using the `addReloadListener()` method available on any configuration object that extends `Reloadable`.

```java
import org.aeonbits.owner.ConfigFactory;
import org.aeonbits.owner.Config;
import org.aeonbits.owner.Reloadable;
import org.aeonbits.owner.event.ReloadListener;
import org.aeonbits.owner.event.ReloadEvent;

@Sources("file:app.properties")
public interface AppConfig extends Config, Reloadable {
    @DefaultValue("localhost")
    String databaseHost();
    
    @DefaultValue("5432")
    Integer databasePort();
}

public class ConfigMonitor {
    public static void main(String[] args) {
        AppConfig config = ConfigFactory.create(AppConfig.class);
        
        // Register anonymous listener
        config.addReloadListener(new ReloadListener() {
            @Override
            public void reloadPerformed(ReloadEvent event) {
                System.out.println("Configuration reloaded at " + event.getTimestamp());
                System.out.println("New database host: " + config.databaseHost());
            }
        });
        
        // Keep application running to receive reload events
    }
}

```

Internally, `ConfigFactory.create()` builds a proxy that maintains a thread-safe list of listeners (see `PropertiesManager.addReloadListener` in the source). When `Config.reload()` or a hot-reload detection triggers a reload, Owner iterates over that list and invokes `listener.reloadPerformed(event)`.

## Accessing ReloadEvent Details

The `ReloadEvent` object passed to your listener contains two critical pieces of information:

- **`event.getConfig()`**: Returns the configuration instance that was reloaded, allowing you to access updated properties.
- **`event.getTimestamp()`**: Returns the Unix timestamp (milliseconds) when the reload occurred.

```java
config.addReloadListener(event -> {
    Reloadable sourceConfig = event.getConfig();
    long reloadTime = event.getTimestamp();
    
    // Log the change for audit purposes
    logger.info("Config {} reloaded at {}", sourceConfig, new Date(reloadTime));
});

```

## Removing a ReloadListener

When a listener is no longer needed—such as during application shutdown or when a component is destroyed—you should unregister it to prevent memory leaks. Use the `removeReloadListener()` method:

```java
ReloadListener myListener = event -> { /* ... */ };
config.addReloadListener(myListener);

// Later, when cleaning up:
config.removeReloadListener(myListener);

```

## Practical Example: Hot-Reload with Listener

For file-based configurations using `@Config.HotReload`, combining automatic reloading with a listener creates a powerful dynamic configuration system. The following example, adapted from [`owner-examples/owner-examples-hotreload/src/main/java/org/aeonbits/owner/examples/AutoReloadExample.java`](https://github.com/matteobaccan/owner/blob/main/owner-examples/owner-examples-hotreload/src/main/java/org/aeonbits/owner/examples/AutoReloadExample.java), demonstrates this pattern:

```java
import org.aeonbits.owner.Config;
import org.aeonbits.owner.ConfigFactory;
import org.aeonbits.owner.Reloadable;
import org.aeonbits.owner.event.ReloadListener;
import org.aeonbits.owner.event.ReloadEvent;

@Config.HotReload(5)  // Check for changes every 5 seconds
@Config.Sources("file:/etc/myapp/config.properties")
public interface DynamicConfig extends Config, Reloadable {
    @DefaultValue("INFO")
    String logLevel();
    
    @DefaultValue("300")
    Integer connectionTimeout();
}

public class HotReloadMonitor {
    public static void main(String[] args) throws InterruptedException {
        DynamicConfig config = ConfigFactory.create(DynamicConfig.class);
        
        // Register listener to react to file changes
        config.addReloadListener(new ReloadListener() {
            @Override
            public void reloadPerformed(ReloadEvent event) {
                System.out.printf("[%d] Config reloaded! New log level: %s, Timeout: %d%n",
                    event.getTimestamp(),
                    config.logLevel(),
                    config.connectionTimeout());
                
                // Trigger cache invalidation or service reconfiguration here
            }
        });
        
        System.out.println("Monitoring config changes. Edit the file to trigger reload...");
        while (true) {
            Thread.sleep(1000);
        }
    }
}

```

In this implementation, Owner monitors the specified file every 5 seconds. When a modification is detected, it reloads the properties and immediately notifies all registered `ReloadListener` instances, allowing the application to adapt to new settings without restart.

## Summary

- Implement `org.aeonbits.owner.event.ReloadListener` to receive callbacks when configuration reloads complete.
- Register listeners using `addReloadListener()` on any configuration instance that implements `Reloadable`.
- Access reload metadata through `ReloadEvent`, including `getConfig()` and `getTimestamp()`.
- Remove listeners with `removeReloadListener()` to prevent memory leaks when components shut down.
- Listeners work with both programmatic reloads (`Config.reload()`) and automatic hot-reloads (`@Config.HotReload`).

## Frequently Asked Questions

### How do I register multiple ReloadListeners on the same configuration instance?

You can call `addReloadListener()` multiple times on the same configuration object. Owner maintains a thread-safe list of listeners and invokes each one sequentially after a reload completes. There is no limit to the number of listeners you can register.

### Can I remove a ReloadListener after registering it?

Yes. Store a reference to your `ReloadListener` implementation and pass it to `removeReloadListener()` when you no longer need notifications. This is important for preventing memory leaks in long-running applications where configuration objects outlive the components that registered the listeners.

### What information does the ReloadEvent object contain?

The `ReloadEvent` object provides two key pieces of metadata: `getConfig()`, which returns the configuration instance that was reloaded, and `getTimestamp()`, which returns the Unix timestamp (in milliseconds) when the reload occurred. You can use these to log changes or trigger conditional logic based on when the reload happened.

### Does the ReloadListener work with both manual and automatic reloads?

Yes. The `ReloadListener` interface is invoked whenever a reload completes, regardless of whether it was triggered manually via `Config.reload()` or automatically through the `@Config.HotReload` annotation. This ensures consistent behavior across programmatic and file-based configuration updates.