{8.2.0-updated} @Bean Annotation

The {@link oaj.annotation.Bean @Bean} annotation is used to tailor how beans are interpreted by the framework.

Bean property inclusion and ordering on a bean class can be done using the {@link oaj.annotation.Bean#properties() @Bean(properties)} annotation.

// Address class with only street/city/state properties (in that order). // All other properties are ignored. @Bean(bpi="street,city,state") public class Address { ... }

Bean properties can be excluded using the {@link oaj.annotation.Bean#bpx() @Bean(bpx)} annotation.

// Address class with only street/city/state properties (in that order). // All other properties are ignored. @Bean(bpx="city,state"}) public class Address { ... }

Bean properties can be sorted alphabetically using {@link oaj.annotation.Bean#sort() @Bean(sort)}

// Address class with only street/city/state properties (in that order). // All other properties are ignored. @Bean(sort=true) public class MyBean { ... }

The {@link oaj.annotation.Bean#propertyNamer() @Bean(propertyNamer)} annotation is used to provide customized naming of properties.

Property namers are used to transform bean property names from standard form to some other form. For example, the {@link oaj.PropertyNamerDLC} will convert property names to dashed-lowercase, and these will be used as attribute names in JSON and element names in XML.

// Define a class with dashed-lowercase property names. @Bean(propertyNamer=PropertyNamerDashedLC.class) public class MyBean { ... }

The {@link oaj.annotation.Bean#interfaceClass @Bean(interfaceClass)} annotation is used to limit properties on beans to specific interface classes. When specified, only the list of properties defined on the interface class will be used during serialization. Additional properties on subclasses will be ignored.

// Parent class @Bean(interfaceClass=A.class) public abstract class A { public String f0 = "f0"; } // Child class public class A1 extends A { public String f1 = "f1"; } JsonSerializer serializer = SimpleJsonSerializer.DEFAULT; A1 a1 = new A1(); String result = serializer.serialize(a1); assertEquals("{f0:'f0'}", result); // Note f1 is not serialized.

Note that this annotation can be used on the parent class so that it filters to all child classes. Or can be set individually on the child classes.

The {@link oaj.annotation.Bean#stopClass @Bean(stopClass)} annotation is another way to limit which properties are serialized (except from the opposite direction). It's identical in purpose to the stop class specified by {@link java.beans.Introspector#getBeanInfo(Class, Class)}. Any properties in the stop class or in its base classes will be ignored during analysis.

For example, in the following class hierarchy, instances of C3 will include property p3, but not p1 or p2.

public class C1 { public int getP1(); } public class C2 extends C1 { public int getP2(); } @Bean(stopClass=C2.class) public class C3 extends C2 { public int getP3(); }

The {@link oaj.annotation.Bean#interceptor() @Bean(interceptor)} annotation and {@link oaj.transform.BeanInterceptor} class can be used to perform interception and inline handling of bean getter and setter calls.

// Interceptor that strips out sensitive information on Address beans. public class AddressInterceptor extends BeanInterceptor<Address> { @Override public Object readProperty(Address bean, String name, Object value) { if ("taxInfo".equals(name)) return "redacted"; return value; } @Override public Object writeProperty(Address bean, String name, Object value) { if ("taxInfo".equals(name) && "redacted".equals(value)) return TaxInfoUtils.lookup(bean.getStreet(), bean.getCity(), bean.getState()); return value; } } // Register interceptor on bean class. @Bean(interceptor=AddressInterceptor.class) public class Address { public String getTaxInfo() {...} public void setTaxInfo(String s) {...} }