| = BlueprintAnnotation |
| |
| == Introduction |
| |
| Blueprint annotation is being prototyped in Apache Aries in trunk/blueprint. |
| The blueprint annotation service is an optional service to the blueprint core and should not affect the blueprint core if annotation supported is not required. |
| If the blueprint annotation service is available, the bundle contains no blueprint definition XML and the bundle contains the manifest header _Bundle-Blueprint-Annotation_ with the value set to true, the blueprint annotation service will attempt to scan the bundle for blueprint annotations, such as @Blueprint, @Bean, @Service, @Reference, @ReferenceList, etc. |
| The blueprint annotation api is available in trunk/blueprint/blueprint-annotation-api module, while the blueprint implementation is available in trunk/blueprint/blueprint-annotatiom-impl module. |
| A blueprint annotated sample is also provided in trunk/blueprint/blueprint-sample-annotation. |
| |
| == Overview of Available blueprint Annotations |
| |
| === @Inject Annotation |
| |
| @Inject annotation can be used to inject fields or methods. |
| |
| .... |
| @Bean(id="bar") |
| public class Bar { |
| |
| @Inject(value="Hello FooBar") |
| private String value; |
| |
| @Inject(ref="blueprintBundleContext") |
| private BundleContext context; |
| ... |
| } |
| .... |
| |
| === @Bean Annotation |
| |
| You can annotate a bean using @Bean annotation. |
| The bean id is currently required, even tho it is possible we may want to the annotation service to auto generate one in the future. |
| Optionally, you can also specify activation, dependsOn, description, scope, factoryRef, factoryMethod and args of the bean. |
| |
| * Example of using args property for the @Bean annotation. |
| |
| .... |
| @Bean(id="accountOne", args=@Arg(value="1")) |
| public class Account { |
| |
| private long accountNumber; |
| |
| public Account(long number) { |
| this.accountNumber = number; |
| } |
| } |
| .... |
| |
| * Example of using factoryMethod and args properties for the @Bean annotation |
| |
| .... |
| @Bean(id="accountTwo", |
| factoryMethod="createAccount", |
| args = @Arg(value="2")) |
| public class StaticAccountFactory { |
| |
| public static Account createAccount(long number) { |
| return new Account(number); |
| } |
| } |
| .... |
| |
| * Example of using factoryRef, factoryMethod, and args properties for the @Bean annotation |
| |
| .... |
| @Bean(id="accountThree", |
| factoryRef="accountFactory", |
| factoryMethod="createAccount", |
| args=@Arg(value="3")) |
| public class NewAccount { |
| |
| private long accountNumber; |
| |
| public NewAccount(long number) { |
| this.accountNumber = number; |
| } |
| ... |
| } |
| .... |
| |
| === @Service, @RegistrationListener, @Register, @Unregister Annotations |
| |
| If you want to register a bean as a service, you can use @Service annotation to do so. |
| You can specify ranking, autoExport, interfaces, serviceProperties and registrationListeners for the service. |
| |
| @Bean(id="foo") |
| @Service(autoExport="all-classes", |
| serviceProperties = |
| @ServiceProperty(key="blueprint.annotation.sample", value="true"), |
| registerationListeners = |
| @RegistrationListener(ref="fooRegistrationListener"), |
| ranking=0) |
| public class Foo implements Serializable { |
| ... |
| } |
| |
| To annotation a class as registration listener, you can use the @RegistrationListener annotation. |
| @Register can be used to annotate the register-method for the registration listener and @Unregister annotation can be used on the unregister-method for the registration listener. |
| |
| .... |
| @Bean(id="fooRegistrationListener") |
| @RegistrationListener |
| public class FooRegistrationListener { |
| |
| @Register |
| public void serviceRegistered(Serializable foo, Map props) { |
| System.out.println("Service registration notification: " + foo + " |
| " + props); |
| } |
| |
| @Unregister |
| public void serviceUnregistered(Foo foo, Map props) { |
| System.out.println("Service unregistration notification: " + foo + |
| " " + props); |
| } |
| |
| } |
| .... |
| |
| === @Reference, @ReferenceList, @ReferenceListener Annotations |
| |
| For a bean that you want to act as a ReferenceListener, you can use @ReferenceListener to annotate the bean class. |
| |
| For the service that you want to inject the reference, you can use the @Inject and @Reference annotation, with the id, serviceInterface, timeout and referenceListeners properties specified for the reference. |
| |
| .... |
| @Bean(id="bindingListener") |
| @ReferenceListener |
| public class BindingListener { |
| |
| @Inject @Reference (id="ref2", |
| serviceInterface = InterfaceA.class, |
| timeout=100, |
| referenceListeners=@ReferenceListener(ref="bindingListener")) |
| private InterfaceA a; |
| ... |
| @Init |
| public void init() { |
| } |
| |
| @Bind |
| public void bind(InterfaceA a, Map props) { |
| this.a = a; |
| this.props = props; |
| } |
| |
| @Unbind |
| public void unbind(InterfaceA a, Map props) { |
| this.a = null; |
| this.props = null; |
| } |
| |
| } |
| .... |
| |
| @ReferenceList is very similar as @Reference, except that the timeout property is not supported in @ReferenceList, while the memberType property is supported in @ReferenceList. |
| This is same as the blueprint XML schema. |
| |
| .... |
| @Bean(id="listBindingListener") |
| @ReferenceListener |
| public class ListBindingListener { |
| |
| @Inject @ReferenceList (id="ref-list", |
| serviceInterface = InterfaceA.class, |
| |
| referenceListeners=@ReferenceListener(ref="listBindingListener")) |
| private InterfaceA a; |
| ... |
| } |
| .... |
| |
| === @Blueprint annotation |
| |
| @Blueprint annotation can be used on any class to annotate the global property of the blueprint bundle, such as defaultActivation, defaultTimeout, defaultAvailability. |
| |
| @Blueprint(defaultActivation="eager", defaultTimeout=300, |
| defaultAvailability="optional") |
| @Bean(id="bar") |
| public class Bar { |
| ... |
| } |
| |
| |
| === Type converters |
| |
| If type converters are desired, you can use the @Bean annotation for it. |
| The blueprint annotation service will recognize it as a type converter if it implements the _org.osgi.service.blueprint.container.Converter_ interface |
| |
| .... |
| @Bean(id="converter1") |
| public class DateTypeConverter implements Converter { |
| |
| @Inject(name="format", value="yyyy.MM.dd") |
| DateFormat dateFormat; |
| ... |
| } |
| .... |
| |
| === Limitation |
| |
| Blueprint Annotation is still prototype work and currently only runtime annotation scanning is supported. |
| While it provides some basic useful functions, there are still many things that you cannot do using annotation, such as inject a list with values, inject inline beans, etc. |