/* * Copyright 2014 Avanza Bank AB * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.avanza.astrix.provider.core; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Used to identify an ApiProvider.<p> * * An ApiProvider is used to define all Astrix-beans that is part of a given api, and * to provide information about how to bind to an instance of a each bean in the api at runtime.<p> * * Astrix defines two distinct types of beans: "libraries" and "services". Simply put, a "service" * can be seen as a bean that uses some kind of remote-service-invocation mechanism to invoke a provider of * a given bean-type, whereas a "library" uses simple in-memory method calls.<p> * * A more formal distinction between a "library" and a "service" is how they are bound at runtime. * For libraries, the class holding this annotation should define a factory method for each exported library bean in * the api. At runtime Astrix binds to a provider of a given bean type by invoking the corresponding factory * method and use the returned instance as provider. Such a method should be annotated with @Library indicating: * * <ol> * <li> That this api provides a library bean of the type returned by the method * <li> That the method should be used as a factory to bind to a provider of the given bean type * </ol> * * The other type of bean is "service". For services Astrix uses an ServiceComponent to bind to a provider * of the given bean type. The ServiceComponent is an extension point to create custom service transports. * A service is defined by annotating a method with @Service indicating: * * <ol> * <li> That this api provides a service of the type returned by the method * <li> Optional information about how to "lookup" the given service, by default Astrix will * lookup a given service using the service-registry. * </ol> * * At runtime, binding of a service is done as follows: * * <ol> * <li> Use the defined lookup mechanism to retrieve runtime service information. The information retrieved * from lookup contains information about (a.) what ServiceComponent to use to bind to the provider and * (b.) all service properties required by the ServiceComponent to bind to a provider. * <li> Use the service-properties and ServiceComponent retrieved from lookup to bind to a provider. * </ol> * * Libraries are sometimes referred to as "statically bound Astrix beans" reflecting that * the Astrix bean instance can't change at runtime. Accordingly, services are sometimes referred to * as "dynamically bound Astrix beans", reflecting that they can be re-bind to a new provider at runtime. * For instance, if a new provider for a given service is registered in the service registry, then * Astrix transparently re-binds the corresponding astrix-bean to the new provider. The new provider * might be using another transport mechanism (as defined by the corresponding ServiceComponent), allowing * transport mechanism to change at runtime.<p> * * Example of a service provider exporting two services that are located using the service registry: * * <pre> * {@literal @}AstrixApiProvider * interface MyServiceProvider { * {@literal @}Service * MyService service(); * * {@literal @}Service * AnotherService anotherService(); * } * </pre> * * * Example library provider exporting a single library Astrix bean. * * <pre> * {@literal @}AstrixApiProvider * class MyLibProvider { * {@literal @}Library * MyLibrary lib() { * return new MyLibImpl(); * } * } * </pre> * * * @author Elias Lindholm (elilin) * */ @Target(value = { ElementType.TYPE}) @Retention(value = RetentionPolicy.RUNTIME) @Documented public @interface AstrixApiProvider { }