Bean Contexts
The Bean Context (BCT — Bean Context Type) is Juneau's core bean-introspection framework. It provides a unified, highly configurable view of Java beans that all serializers, parsers, and other framework components share.
Every marshaller in Juneau extends MarshallingContext, which means a single set of bean-modeling
settings controls how beans are discovered, read, and written across all formats — JSON, XML, YAML,
CSV, MessagePack, and the rest — with no per-format configuration duplication.
The framework splits into two layers:
| Layer | Location | Responsibility |
|---|---|---|
| Bean modeling | juneau-commons | Introspect classes, discover properties, apply @BeanType/@BeanProp/@BeanIgnore/@BeanCtor |
| Marshalling | juneau-marshall | Extend the bean model with ClassMeta, type swaps, bean dictionaries, format-specific options |
MarshallingContext — the Configuration Context
MarshallingContext
is the root configuration object for bean introspection and marshalling.
All serializers and parsers (and their builders) extend from it, so they inherit every builder
method on the context directly.
Instances are:
- Immutable — constructed once via a fluent builder and never changed thereafter.
- Thread-safe — freely shared across serializers and threads.
- Cache-sharing — contexts with the same settings reuse the same
ClassMetacache, so expensive reflective analysis of a given class happens only once.
// Create a standalone context (useful for programmatic bean introspection
// without going through a full serializer).
MarshallingContext ctx = MarshallingContext
.create()
.beansRequireDefaultConstructor() // Tighten bean detection
.beanFieldVisibility(Visibility.ANY) // Include private fields
.notBeanClasses(MyRawType.class) // Exclude this class from bean treatment
.build();
The static constant MarshallingContext.DEFAULT provides a pre-built, zero-config context for
quick use.
MarshallingSession — the Per-Operation Session
MarshallingSession
is an ephemeral, per-operation companion to MarshallingContext.
Sessions hold request-scoped state such as locale, time zone, active view, and media type.
They are lightweight to create and are typically not shared across threads.
// Open a session for the DEFAULT context.
MarshallingSession session = MarshallingContext.DEFAULT_SESSION; // singleton no-op session
// Or create one with per-call settings.
MarshallingSession session = MarshallingContext.DEFAULT.createSession();
Sessions are the entry point for creating BeanMap instances (see below).
BeanMap — Beans as Maps
BeanMap
wraps a Java bean inside a Map<String, Object> interface, letting properties be read and written
via the standard get/put methods. All serializers use BeanMap internally to traverse a
bean's properties without generating intermediate structures. Although used internally by every
serializer and parser, it is often useful on its own.
public class Person {
public String name = "John Smith";
public int age = 21;
}
// Wrap an existing bean.
BeanMap<Person> bm = MarshallingContext.DEFAULT_SESSION.toBeanMap(new Person());
bm.put("name", "Jane Doe");
String name = (String) bm.get("name"); // "Jane Doe"
// Typed accessor — convert the property value on read.
int age = bm.get("age", int.class);
// Create a new bean through the map.
BeanMap<Person> bm2 = MarshallingContext.DEFAULT_SESSION.newBeanMap(Person.class);
bm2.put("name", "Alice");
bm2.put("age", 30);
Person p = bm2.getBean();
BeanMap iteration follows a deterministic property order:
explicit @BeanType(properties=...) list → alphabetical (default) → natural reflection order
when @BeanType(unsorted=true) is set.
BeanMeta — Bean Class Metadata
BeanMeta
is the compiled introspection record for a single bean class.
It holds the complete, resolved list of
BeanPropertyMeta
entries — one per logical property — including the underlying field or getter/setter pair, resolved
generic types, and any applied annotations.
Instances are built once and cached by the context. Retrieve one via:
BeanMeta<Person> meta = MarshallingContext.DEFAULT_SESSION.getBeanMeta(Person.class);
for (BeanPropertyMeta prop : meta) {
System.out.println(prop.getName() + " : " + prop.getClassMeta().getInnerClass());
}
ClassMeta — Type Metadata Cache
ClassMeta
extends BeanMeta with marshalling-layer knowledge: whether a class is a bean, a collection,
a map, a primitive, an enum, or something else (the Category enum covers ~20 categories).
It also records the active object swaps and format overrides for that type.
ClassMeta<Person> cm = MarshallingContext.DEFAULT.getClassMeta(Person.class);
cm.isBean(); // true
cm.isMap(); // false
Core Annotations
The bean-modeling layer lives in juneau-commons and uses a trio of annotations that are
independent of any marshalling concern. The marshalling layer in juneau-marshall extends each
one with a sibling that carries format-specific attributes.
@BeanType — class-level control
Applied to a class to declare the canonical property list, sorting, excluded properties, stop
class, and more. The marshalling-layer sibling is @Marshalled.
// Keep only "id" and "name"; expose them in that exact order.
@BeanType(properties = "id,name")
public class Person {
public int id;
public String name;
public String internalToken; // excluded — not in properties list
}
// Exclude a property by name (useful when you cannot edit the class).
@BeanType(excludeProperties = "password")
public class Account { ... }
@BeanProp — property-level control
Applied to a field, getter, setter, or constructor parameter to rename a property, mark it
read-only/write-only, specify a concrete type, or supply a factory.
The marshalling-layer sibling is @MarshalledProp.
public class Contact {
// Rename the serialized property key.
@BeanProp("full_name")
public String fullName;
// Read-only — serialized but ignored on parse.
@BeanProp(ro = "true")
public String getCreatedAt() { ... }
// Write-only — accepted on parse but not serialized.
@BeanProp(wo = "true")
public void setPassword(String pw) { ... }
}
@BeanIgnore — exclusion
Applied to a class, field, method, or constructor to exclude it from bean introspection.
On a class, marks it as not a bean (the marshaller falls back to toString() or a registered
swap). On a member, removes it from the property set.
// Entire class: never treated as a bean.
@BeanIgnore
public class RawToken { ... }
// Individual member: hidden from serialization and parsing.
public class Order {
public String orderId;
@BeanIgnore
public String getDebugString() { ... } // excluded from marshalling
}
@BeanCtor — constructor-based deserialization
Applied to a constructor to map its parameters onto the bean's logical property names.
Required when a bean is read-only (no setters) and must be instantiated during parsing.
Java Records detect their canonical constructor automatically, so @BeanCtor is optional there.
public class Point {
public final int x, y;
@BeanCtor({"x","y"})
public Point(int x, int y) {
this.x = x; this.y = y;
}
}
// Parser can now reconstruct Point from {"x":1,"y":2}.
Point p = Json.to("{x:1,y:2}", Point.class);
Swaps and Filters
When a class cannot be introspected as a bean (or needs a different wire representation), the bean context delegates to object swaps — pluggable converters registered on the context builder:
MarshallingContext ctx = MarshallingContext
.create()
.calendarFormat(CalendarFormat.ISO_INSTANT) // Instant → ISO-8601 string
.build();
The MarshalledFilter class (implements BeanFilter) is the programmatic API for applying
bean-level overrides such as additional include/exclude lists or property namers without touching
the annotated source class — useful for third-party types.
- Swap Basics for the full object-swap reference.
- Bean Dictionary Basics for polymorphic type resolution.
Builder Configuration
Every marshaller builder inherits the full set of
MarshallingContext.Builder
settings.
Common properties include:
| Builder method | Effect |
|---|---|
beanFieldVisibility(Visibility) | Include PRIVATE, PROTECTED, or PUBLIC fields as properties |
beanMethodVisibility(Visibility) | Visibility threshold for getter/setter discovery |
beansRequireDefaultConstructor() | Only treat classes with a public no-arg constructor as beans |
beansRequireSerializable() | Only treat Serializable classes as beans |
notBeanClasses(Class...) | Exclude specific classes from bean treatment |
notBeanPackages(String...) | Exclude entire packages from bean treatment |
sortProperties() | Force alphabetical property order globally |
ignoreUnknownBeanProperties() | Silently skip unrecognized keys during parsing |
swaps(Class...) | Register object-swap converters |
beanDictionary(Class...) | Register types for polymorphic _type resolution |
Any setting that can be applied via a builder can equally be applied via a @MarshalledConfig
config annotation, allowing serializer settings to live on an annotated class and be applied
via builder.applyAnnotations(MyAnnotatedClass.class).
// Config annotation on a class — useful in REST servlet hierarchies.
@MarshalledConfig(sortProperties = "true", ignoreUnknownBeanProperties = "true")
public class MyApiResource { ... }
// Apply the annotations to a serializer at build time.
JsonSerializer s = JsonSerializer.create()
.applyAnnotations(MyApiResource.class)
.build();
- Java Beans Support for property-detection rules and examples.
- Java Records Support for record-specific behavior.
- Context Annotations for the config-annotation reference.
In This Section
📄️ 2.2.3.1. Java Beans Support
Out-of-the-box, Juneau supports marshalling of Java beans with standard public getters and setters, public fields, and
📄️ 2.2.3.2. Java Records Support
Juneau supports serialization and parsing of Java records out of the box. Records are treated as beans whose
📄️ 2.2.3.3. @BeanType Annotation
The @BeanType annotation is applied to classes to control bean introspection and modeling.
📄️ 2.2.3.4. @BeanProp Annotation
The @BeanProp annotation is applied to bean fields, getter/setter methods, and constructor parameters
📄️ 2.2.3.5. @BeanCtor Annotation
The @BeanCtor annotation is applied to bean constructors to map constructor arguments to property
📄️ 2.2.3.6. @BeanIgnore Annotation
The @BeanIgnore annotation
📄️ 2.2.3.7. @NameProperty Annotation
The @NameProperty annotation is used to identify a setter method or field for setting the name of a POJO as it's known by its parent object.
📄️ 2.2.3.8. @ParentProperty Annotation
The @ParentProperty annotation is used to identify a setter method or field for adding a parent reference to a child object.
📄️ 2.2.3.9. POJO Builders
Juneau parsers can use builders to instantiate POJOs.
📄️ 2.2.3.10. Bypass Serialization using Readers and InputStreams
Juneau serializers treat instances of Readers and InputStreams special by simply serializing their contents directly
📄️ 2.2.3.11. View-Based Projection
View-based projection lets you define named views — property subsets — on a bean and choose which view
📄️ 2.2.3.12. @Marshalled Annotation
The @Marshalled annotation is a
📄️ 2.2.3.13. @MarshalledAs Enum
MarshalledAs is an enum in
📄️ 2.2.3.14. MarshalledFilter
MarshalledFilter is the concrete BeanFilter: per-class control of bean properties, ordering, exclusions and naming during marshalling.
📄️ 2.2.3.15. @Example Annotation
The @Example annotation in