# Annotations

<!-- markdownlint-disable blanks-around-fences -->
<?code-excerpt path-base="examples/java/spring-starter"?>

For most users, the out-of-the-box instrumentation is completely sufficient and
nothing more has to be done. Sometimes, however, users wish to create
[spans](/docs/concepts/signals/traces/#spans) for their own custom code without
needing to make many code changes.

If you add the `WithSpan` annotation to a method, the method is wrapped in a
span. The `SpanAttribute` annotation allows you to capture the method arguments
as attributes.

<!-- prettier-ignore-start -->
<?code-excerpt "src/main/java/otel/TracedClass.java"?>
```java
package otel;

import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.instrumentation.annotations.SpanAttribute;
import io.opentelemetry.instrumentation.annotations.WithSpan;
import org.springframework.stereotype.Component;

/** Test WithSpan */
@Component
public class TracedClass {

  @WithSpan
  public void tracedMethod() {}

  @WithSpan(value = "span name")
  public void tracedMethodWithName() {
    Span currentSpan = Span.current();
    currentSpan.addEvent("ADD EVENT TO tracedMethodWithName SPAN");
    currentSpan.setAttribute("isTestAttribute", true);
  }

  @WithSpan(kind = SpanKind.CLIENT)
  public void tracedClientSpan() {}

  @WithSpan
  public void tracedMethodWithAttribute(@SpanAttribute("attributeName") String parameter) {}
}
```
<!-- prettier-ignore-end -->

> [!NOTE]
>
> The OpenTelemetry annotations use Spring AOP based on proxies.
>
> These annotations work only for the methods of the proxy. You can learn more
> in the
> [Spring documentation](https://docs.spring.io/spring-framework/reference/core/aop/proxying.html).
>
> In the following example, the `WithSpan` annotation won't do anything when the
> GET endpoint is called:
>
> ```java
> @RestController
> public class MyControllerManagedBySpring {
>
>     @GetMapping("/ping")
>     public void aMethod() {
>         anotherMethod();
>     }
>
>     @WithSpan
>     public void anotherMethod() {
>     }
> }
> ```

<div class="alert alert-primary" role="alert"><div class="h4 alert-heading" role="heading">Note</div>



To be able to use the OpenTelemetry annotations, you have to add the Spring Boot
Starter AOP dependency to your project:

   <ul class="nav nav-tabs" id="tabs-0" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-00-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-00-00" role="tab"
          data-td-tp-persist="maven (`pom.xml`)" aria-controls="tabs-00-00" aria-selected="true">
        Maven (<code>pom.xml</code>)
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-00-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-00-01" role="tab"
          data-td-tp-persist="gradle (`build.gradle`)" aria-controls="tabs-00-01" aria-selected="false">
        Gradle (<code>build.gradle</code>)
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-0-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-00-00" role="tabpanel" aria-labelled-by="tabs-00-00-tab" tabindex="0">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="nt">&lt;dependencies&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;dependency&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;groupId&gt;</span>org.springframework.boot<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;artifactId&gt;</span>spring-boot-starter-aop<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;/dependency&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/dependencies&gt;</span>
</span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-00-01" role="tabpanel" aria-labelled-by="tabs-00-01-tab" tabindex="0">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-kotlin" data-lang="kotlin"><span class="line"><span class="cl"><span class="n">dependencies</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">implementation</span><span class="p">(</span><span class="s2">&#34;org.springframework.boot:spring-boot-starter-aop&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div>
    </div>
</div>


</div>


You can disable the OpenTelemetry annotations by setting the
`otel.instrumentation.annotations.enabled` property to `false`.

You can customize the span by using the elements of the `WithSpan` annotation:

| Name    | Type       | Description           | Default Value       |
| ------- | ---------- | --------------------- | ------------------- |
| `value` | `String`   | Span name             | ClassName.Method    |
| `kind`  | `SpanKind` | Span kind of the span | `SpanKind.INTERNAL` |

You can set the attribute name from the `value` element of the `SpanAttribute`
annotation:

| Name    | Type     | Description    | Default Value         |
| ------- | -------- | -------------- | --------------------- |
| `value` | `String` | Attribute name | Method parameter name |

## Next steps

Beyond the use of annotations, the OpenTelemetry API allows you to obtain a
tracer that can be used [custom instrumentation](../api).
