Annotation Interface BeanProp
The bean-modeling sibling of @MarshalledProp.
Where @MarshalledProp (in dictionary, format, and properties), this annotation carries the
attributes that describe the bean property itself — its name, accessibility (read/write only),
concrete type, generic type parameters, element type, and the bean factory used to instantiate
its value.
Splitting the annotations lets a property participate in the bean model (for example, to declare
its name or read-only semantics) without dragging in any marshalling concerns, and lets the
bean-modeling layer live in
Can be used in the following locations:
- Bean fields, getter methods, and setter methods.
- Constructor parameters.
See Also:
-
Optional Element Summary
Optional ElementsModifier and TypeOptional ElementDescriptionString[]Optional description for the exposed API.Class<?>Element type for streaming/consuming bean properties.Class<? extends BeanFactory>Bean factory class for this property's value.Identifies the name of the property.Class<?>[]For bean properties of maps and collections, this annotation can be used to identify the class types of the contents of the bean property object when the generic parameter types are interfaces or abstract classes.booleanMarks this property as required on input.Identifies a property as read-only.Short, concise summary of the exposed API.Class<?>Identifies a specialized class type for the property.A synonym forname().Identifies a property as write-only.
-
Element Details
-
description
Optional description for the exposed API.- Returns:
- The annotation value.
- Since:
- 9.2.0
- Default:
- {}
-
summary
Short, concise summary of the exposed API.Intended as a brief, single-line description suitable for AI/LLM consumption, compact documentation, or any context where brevity matters. See
Schema.summary()for the canonical definition; this field is the bean-property-level counterpart.- Returns:
- The annotation value.
- Since:
- 10.0.0
- Default:
- ""
-
elementType
Class<?> elementTypeElement type for streaming/consuming bean properties.Specifies the element type for properties of type
Stream,BeanSupplier,BeanConsumer, orBeanChannelwhen type erasure prevents the framework from inferring the generic type argument at runtime.This attribute also supports:
- Narrowing - Specify a more specific subtype than the declared type
- Concrete implementation - Specify a concrete class for an abstract/interface element type
Example:
public class OrderCollection {// Stream property - element type cannot be inferred at runtime due to erasure @BeanProp (elementType=Order.class )public Stream<Order> getOrders() { ... }// BeanChannel with concrete impl specified instead of abstract element type @BeanProp (elementType=ConcreteItem.class )public BeanChannel<AbstractItem> getItems() { ... } }See Also:
- Returns:
- The annotation value.
- Default:
- void.class
-
factory
Class<? extends BeanFactory> factoryBean factory class for this property's value.Specifies a
BeanFactoryclass to use when instantiating the value of this specific bean property, overriding the class-levelBeanType.factory()if present.When a factory class is specified, the framework resolves it in the following order:
- Look up the factory class in the configured
BeanStore - Attempt direct instantiation via no-arg constructor or
getInstance()static method - Throw
IllegalArgumentExceptionif both fail
Example:
public class MyBean {@BeanProp (factory=ItemChannelFactory.class , elementType=Item.class )public BeanChannel<Item> getItems() { ... } }See Also:
- Returns:
- The annotation value.
- Default:
- org.apache.juneau.commons.function.BeanFactory.Void.class
- Look up the factory class in the configured
-
name
Identifies the name of the property.Normally, this is automatically inferred from the field name or getter method name of the property. However, this property can be used to assign a different property name from the automatically inferred value.
Dynamic beans
On a field whose type is not a
Map,"*" does not create a dynamic property: the property name is the field name (same as omittingname/value), while other attributes on this annotation still apply.The bean property named
"*" is the designated "dynamic property" which allows for "extra" bean properties not otherwise defined.The following examples show how to define dynamic bean properties.
// Option #1 - A simple public Map field. // The field name can be anything. public class BeanWithDynaField {@BeanProp (name="*" )public Map<String,Object>extraStuff =new LinkedHashMap<>(); }// Option #2 - Getters and setters. // Method names can be anything. // Getter must return a Map with String keys. // Setter must take in two arguments. public class BeanWithDynaMethods {@BeanProp (name="*" )public Map<String,Object> getMyExtraStuff() { ... }@BeanProp (name="*" )public void setAnExtraField(Stringname , Objectvalue ) { ... } }Note that the@Nameannotation can also be used for identifying a property name.- Returns:
- The annotation value.
- Default:
- ""
-
params
For bean properties of maps and collections, this annotation can be used to identify the class types of the contents of the bean property object when the generic parameter types are interfaces or abstract classes.Example:
public class MyBean {// Identify concrete map type with String keys and Integer values. @BeanProp (type=HashMap.class , params={String.class ,Integer.class })public Mapp1 ; }- Returns:
- The annotation value.
- Default:
- {}
-
required
boolean requiredMarks this property as required on input.When
true , parsers (andMap-to-bean conversion) throw aorg.apache.juneau.marshall.parser.MissingRequiredPropertyExceptionif the input does not contain this property. The check runs once per bean, before the bean is constructed, so records and constructor-argument beans get a clear error instead of a constructor failure."Present" means the key appears in the input. An explicit
null value counts as present; use your own validation (or a compact record constructor) to reject null values.The flag is OR-merged across the field, getter and setter: annotating any one of them makes the property required. Wrapping an existing object (for example
MarshallingSession.toBeanMap(Object)) never checks.This attribute is independent of
@Schema(required), which only affects generated schema documentation and HTTP part validation.Example:
public record Person(@BeanProp (required=true ) Stringname , Integerage ) {}// Throws MissingRequiredPropertyException: // Missing required properties on bean class 'Person': [name] JsonParser.DEFAULT .read("{\"age\":30}" , Person.class );// OK: explicit null counts as present. JsonParser.DEFAULT .read("{\"name\":null}" , Person.class );Notes:
- A required property must be writable (a field, setter or constructor argument). Marking a read-only property required fails when the bean metadata is built.
- For builder-based beans, put the annotation on the builder's setter.
- On a non-record bean, put the annotation on the field or getter; it is not read from constructor parameters.
-
In REST methods, a missing required property in an
@Contentbody produces400 Bad Request .
- Returns:
true if this property must be present in the input.
- Default:
- false
-
ro
Identifies a property as read-only.Serializers will serialize such properties as usual, but parsers will silently ignore them.
Example:
public class MyBean {@BeanProp (ro="true" )public float price ; }Notes:
- Java Records: Marking record components as read-only is not supported during parsing. Because records are immutable, all components must be provided to the canonical constructor. Read-only components will be serialized as usual, but the parser will be unable to instantiate the record if the read-only component values are missing from the input.
- Returns:
- The annotation value.
- Default:
- ""
-
type
Identifies a specialized class type for the property.Normally this can be inferred through reflection of the field type or getter return type. However, you'll want to specify this value if you're parsing beans where the bean property class is an interface or abstract class to identify the bean type to instantiate. Otherwise, you may cause an
InstantiationExceptionwhen trying to set these fields.This property must denote a concrete bean class with a no-arg constructor.
Example:
public class MyBean {// Identify concrete map type. @BeanProp (type=HashMap.class )public Mapp1 ; }- Returns:
- The annotation value.
- Default:
- void.class
-
value
A synonym forname().The following annotations are equivalent:
@BeanProp (name="foo" )@BeanProp ("foo" )- Returns:
- The annotation value.
- Default:
- ""
-
wo
Identifies a property as write-only.Parsers will parse such properties as usual, but serializers will silently ignore them.
Example:
public class MyBean {@BeanProp (wo="true" )public float price ; }- Returns:
- The annotation value.
- Default:
- ""
-