# How to Use the @Key Annotation to Map Method Names to Custom Property Keys in Owner

> Learn how to use the @Key annotation in Owner to map interface methods directly to custom property keys overriding default behavior. Simplify your configuration mapping.

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

---

**The `@Key` annotation lets you explicitly bind interface methods to custom property keys, overriding Owner's default behavior of converting camelCase method names to dot-separated keys.**

Owner is a Java library that implements **interface-based** configuration management. When your property files use keys that differ from your Java method names, the `@Key` annotation provides the exact mapping needed to bridge the two.

## Understanding the @Key Annotation Definition

The `@Key` annotation is declared inside `org.aeonbits.owner.Config` as a runtime-visible method-target annotation. In [`owner/src/main/java/org/aeonbits/owner/Config.java`](https://github.com/matteobaccan/owner/blob/main/owner/src/main/java/org/aeonbits/owner/Config.java), the annotation is defined as:

```java
@Retention(RUNTIME)
@Target(METHOD)
@Documented
@interface Key {
    String value();               // the exact property key to look up
}

```

This definition ensures that the annotation is retained at runtime and can only be applied to interface methods. The `value()` field accepts the exact string Owner uses to look up the property from loaded sources.

## How Owner Resolves Property Keys

When Owner generates a runtime implementation of your configuration interface—via [`owner/src/main/java/org/aeonbits/owner/Factory.java`](https://github.com/matteobaccan/owner/blob/main/owner/src/main/java/org/aeonbits/owner/Factory.java)—it follows a deterministic lookup algorithm to resolve values:

1. **Load sources** according to `@Sources` or the default search order (files, classpath resources, system properties, etc.).
2. **Inspect each method** in the interface:
   - If `@Key` is present, use the supplied string as the lookup key.
   - Else, derive the key from the method name (converting camelCase to dot-separated format).
3. **Retrieve the value** from the merged properties map.
4. **Convert** the raw `String` to the method's declared return type (int, boolean, enum, etc.).
5. **Apply** additional annotations (`@DefaultValue`, `@ConverterClass`, `@EncryptedValue`) if present.

The annotation value is used verbatim for the lookup, though it can contain **variable placeholders** (`${…}`) that are resolved before the key is used (introduced in Owner 1.0.6).

## Practical @Key Annotation Examples

### Basic Property Key Mapping

When your properties file uses verbose or namespaced keys, map them directly to concise method names. Consider a `ServerConfig.properties` file:

```properties
server.http.port=80
server.host.name=foobar.com
server.max.threads=100

```

Define the mapping in your interface:

```java
public interface ServerConfig extends Config {
    @Key("server.http.port")
    int port();

    @Key("server.host.name")
    String hostname();

    @Key("server.max.threads")
    @DefaultValue("42")
    int maxThreads();
}

```

As shown in [`owner-site/site/docs/usage.md`](https://github.com/matteobaccan/owner/blob/main/owner-site/site/docs/usage.md), the `@Key` annotation tells Owner to read exactly the keys specified, regardless of the method names.

### Dynamic Keys with Variable Expansion

You can inject variables into the `@Key` value to select different properties based on runtime context. This requires Owner 1.0.6 or later.

Given this properties file:

```properties
servers.dev.port=6000
servers.uat.port=60020
servers.prod.port=600

```

Use variable expansion to select the environment dynamically:

```java
@Sources("classpath:org/aeonbits/owner/variableexpansion/KeyExpansionExample.properties")
public interface EnvConfig extends Config {
    @DefaultValue("dev")
    String env();                     // can be overridden via system/property

    @Key("servers.${env}.port")
    int port();                       // resolves to servers.dev.port, etc.
}

```

The `${env}` placeholder is replaced with the value returned by the `env()` method (or its default) before the property lookup occurs, as documented in [`owner-site/site/docs/variables-expansion.md`](https://github.com/matteobaccan/owner/blob/main/owner-site/site/docs/variables-expansion.md).

## Validating @Key Mappings in Unit Tests

The test suite validates that `@Key` correctly reads custom keys from various sources including XML. In [`owner/src/test/java/org/aeonbits/owner/xml/XmlSourceTest.java`](https://github.com/matteobaccan/owner/blob/main/owner/src/test/java/org/aeonbits/owner/xml/XmlSourceTest.java), the mapping is verified:

```java
public interface ServerConfig extends Config, Accessible {
    @Key("server.http.port")
    int httpPort();

    @Key("server.http.hostname")
    String httpHostname();
}

@Test
public void testXmlReading() {
    ServerConfig cfg = factory.create(ServerConfig.class);
    assertEquals(80, cfg.httpPort());
    assertEquals("localhost", cfg.httpHostname());
}

```

This demonstrates that Owner correctly associates the annotated keys with the underlying XML structure, proving the abstraction works across different configuration formats.

## Summary

- The `@Key` annotation is defined in `org.aeonbits.owner.Config` and targets methods exclusively.
- It overrides the default key derivation logic, allowing any string to serve as the property lookup key.
- Variable placeholders like `${variable}` inside `@Key` values are resolved at runtime before lookup (Owner 1.0.6+).
- The annotation works uniformly across all property sources, including `.properties`, XML, and system properties.
- Owner's `Factory` class processes these annotations when generating the dynamic proxy implementation.

## Frequently Asked Questions

### What happens if I don't use @Key on a method?

Owner converts the method name from camelCase to a dot-separated property key automatically. For example, a method named `serverPort()` becomes the lookup key `server.port`.

### Can I use variables inside the @Key annotation value?

Yes. Since Owner 1.0.6, you can include placeholders like `${env}` inside the `@Key` string. Owner resolves these variables using values from the same configuration interface or system properties before performing the property lookup.

### Does @Key work with all property sources?

Yes. The `@Key` annotation is source-agnostic. Whether your configuration comes from properties files, XML documents, JSON, or system environment variables, Owner uses the annotated key to retrieve the value from the merged configuration map.

### Where is the @Key annotation processed in the Owner source code?

The annotation is defined in [`owner/src/main/java/org/aeonbits/owner/Config.java`](https://github.com/matteobaccan/owner/blob/main/owner/src/main/java/org/aeonbits/owner/Config.java). The runtime processing logic that reads `@Key` values and performs the property lookup resides in [`owner/src/main/java/org/aeonbits/owner/Factory.java`](https://github.com/matteobaccan/owner/blob/main/owner/src/main/java/org/aeonbits/owner/Factory.java), which generates the dynamic proxy implementation of your configuration interface.