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.