Annotation Interface Bean


Bean injection annotation.

Used on methods and fields of BeanStore-managed objects to denote methods and fields that override and customize beans used by the framework.

Example

// Rest resource that uses a customized logger. @Rest public class MyRest extends BasicRestServlet { // Option #1: As a field. @Bean RichLogger myLogger = RichLogger.getLogger("mylogger"); // Option #2: As a method. @Bean public RichLogger myLogger() { return RichLogger.getLogger("mylogger"); } }

The name()/value() attributes are used to differentiate between named beans.

Example

// Customized default request headers. @Bean("defaultRequestHeaders") HeaderList defaultRequestHeaders = HeaderList.create().set(ContentType.TEXT_PLAIN).build(); // Customized default response headers. @Bean("defaultResponseHeaders") HeaderList defaultResponseHeaders = HeaderList.create().set(ContentType.TEXT_PLAIN).build();

The methodScope() attribute is used to define beans in the scope of specific @RestOp-annotated methods.

Example

// Set a default header on a specific REST method. // Input parameter is the default header list builder with all annotations applied. @Bean(name="defaultRequestHeaders", methodScope="myRestMethod") public HeaderList.Builder myRequestHeaders(HeaderList.Builder builder) { return builder.set(ContentType.TEXT_PLAIN); } // Method that picks up default header defined above. @RestGet public Object myRestMethod(ContentType contentType) { ... }

This annotation can also be used to inject arbitrary beans into the bean store which allows them to be passed as resolved parameters on @RestOp-annotated methods.

Example

// Custom beans injected into the bean store. @Bean MyBean myBean1 = new MyBean(); @Bean("myBean2") MyBean myBean2 = new MyBean(); // Method that uses injected beans. @RestGet public Object doGet(MyBean myBean1, @Name("myBean2") MyBean myBean2) { ... }

This annotation can also be used on uninitialized fields. When fields are uninitialized, they will be set during initialization based on beans found in the bean store.

Example

// Fields that get set during initialization based on beans found in the bean store. @Bean RichLogger logger; @Bean BeanStore beanStore; // Note that the BeanStore itself can be accessed this way.

Notes:
  • Methods and fields can be static or non-static.
  • Any injectable beans (including spring beans) can be passed as arguments into methods.
  • Bean names are required when multiple beans of the same type exist in the bean store.
  • @Bean methods and fields may have any visibility (public, protected, package-private or private). Non-public members are made accessible before use, so the containing package must be opened to module org.apache.juneau.commons when running on the module path.
  • By default, the injected bean scope is class-level (applies to the entire class). The methodScope() annotation can be used to apply to method-level only (when applicable).
Bean names:

Each @Bean method registers its own result. Two methods returning the same type are distinguished by name, and both beans are kept. Factory methods on @Rest resources and @Configuration classes are the common use.

Example:

// Two beans of the same type, distinguished by name. Each method's own result is registered. @Rest public class MyResource extends BasicRestServlet { @Bean(name="db") HealthIndicator dbIndicator() { return () -> Health.up("db").build(); } @Bean(name="cache") HealthIndicator cacheIndicator() { return () -> Health.up("cache").build(); } }

Precedence (since 10.0.0):

@Bean acts as a programmable default, analogous to Spring's @ConditionalOnMissingBean. When a REST context resolves a framework-managed bean (RichLogger, EncoderSet, SerializerSet, ParserSet, ThrownStore, Config, VarResolver, HttpPartSerializer, HttpPartParser, etc.), the lookup walks the following tiers in order, returning the first hit:

  1. Overriding-parent bean store — Spring beans (in juneau-rest-server-springboot deployments, via SpringBeanStore), or any bean reachable through the configured overriding-parent bean-store chain.
  2. @Bean method/field on the resource class — registered as a regular bean-store entry, beating the framework default.
  3. Memoizer-backed framework default — built into the context as a default supplier.

In other words: a Spring @Bean of type RichLogger wins over a @Bean RichLogger method on the same servlet, which in turn wins over the framework's built-in class-name-based default logger. Non-Spring deployments have an empty overriding-parent layer, so the chain naturally collapses to @Bean > default.

Prior to 10.0 the order was @Bean > Spring > default. See the 10.0.0 release notes for migration guidance if you need to keep that legacy behavior (typically by removing the Spring @Bean or marking the @Bean method's type with a Spring-native override such as @Primary).

See Also:
  • Optional Element Summary

    Optional Elements
    Modifier and Type
    Optional Element
    Description
    Optional description for the exposed API.
    The short names of the methods that this annotation applies to.
    The bean name to use to distinguish beans of the same type for different purposes.
    int
    Optional ordering value used when exporting ordered bean collections.
    Same as name().
  • Element Details

    • description

      Optional description for the exposed API.
      Returns:
      The annotation value.
      Since:
      9.2.0
      Default:
      {}
    • methodScope

      The short names of the methods that this annotation applies to.

      Can use "*" to apply to all methods.

      Ignored for class-level scope.

      Returns:
      The short names of the methods that this annotation applies to, or empty if class-scope.
      Default:
      {}
    • name

      The bean name to use to distinguish beans of the same type for different purposes.

      For example, there are two HeaderList beans: "defaultRequestHeaders" and "defaultResponseHeaders". This annotation would be used to differentiate between them.

      Returns:
      The bean name to use to distinguish beans of the same type for different purposes, or blank if bean type is unique.
      Default:
      ""
    • value

      Same as name().
      Returns:
      The bean name to use to distinguish beans of the same type for different purposes, or blank if bean type is unique.
      Default:
      ""
    • priority

      Optional ordering value used when exporting ordered bean collections.

      Lower values are higher precedence. If both Order and this value are present on the same contribution source, Order wins.

      Returns:
      The priority value.
      Default:
      1073741823