Apache Blueprint is container specification, which
defines the dependency injection for OSGi. It is a dependency injection framework for
OSGi bundle development.
Liferay 7/DXP came up with OSGi support. We can use Apache Blueprint framework to develop Liferay Application OSGi bundles. We can use either OSGi Declarative Services (DS) or Apache Blueprint to develop Liferay bundles. This article gives basic idea of Apache Blueprint framework.
We already know Declarative Services in OSGi. Apache Blueprint is similar to DS. Blueprint is enable component services make
it available and unavailable at any point of time. Apache Blueprint based on
OSGi Compendium R4.2 specifications.
Apache Blueprint is container specification based on
OSGi extender pattern. Extender pattern is very used pattern in OSGi
environment to extend semantics of bundle by adding new MANIFEST headers. To
add addition features to existing bundle nature, we will use OSGi extender
pattern. Best example is OSGi
Declarative Services. OSGi Declarative Services used extender pattern so
that it will provide dynamic nature to the components and it services.
Apache
Blueprint is used extender pattern as well. Apache Blue print extender bundles monitor
the bundles state in the framework and perform the action on behalf of the
bundle based on their actual state.
Extender bundle is responsible to identify the bundle
is blueprint bundle or not, once the bundle activated the OSGi container. Extender
bundle will look for the Blueprint xml files in the bundle. If any bundle have
Blueprint xml files then it will treat bundle as blue print framework bundle.
Usually blueprint xml files located in the fixed location in the place OSGI-INF/blueprint/ directory or are
specified explicitly in the Bundle-Blueprint manifest header.
Once bundle is blueprint bundle, then it will create
the Blueprint container for the bundle and it is responsible for following
actions. These actions are similar to Spring Framework Dependency Injection. If
we are familiar with Spring framework then it will be easy to understand OSGi
dependency Injection through Blueprint framework.
XML
file parsing
Instantiate
the components
Wiring
the component together
Registering
the services
Looking
up service references
Blueprint
XML Configuration
Blueprint framework uses the XML configurations to
declare beans and its wiring. Blueprint container read this xml configuration
file to instantiate and wiring the beans. Blueprint is top-level xml tag.
The following is basic declaration which specify the
blueprint configuration
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> ... </blueprint> |
The XML namespace identifies the document as conforming
to the Blueprint version 1.0.0. The top-level blueprint element identifies the
document as a blueprint module definition.
Bean
Declaration
Blueprint uses the bean tag to declare beans. Bean tag
have id attribute, which is unique identification for bean.
The
following is example of bean declaration.
<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> <bean id="helloServiceOne" class="com.liferaysavvy.blueprint.HelloService" /> </blueprint> |
Bean
Constriction
Blueprint container will look for right constrictor to
instantiate the beans. This information provided as bean attributes or its
child tags. Instantiation can be happen with the constrictor or factory method. By default, the Blueprint
Container uses the number and order of the argument elements in XML to find the
right constructor or method.
To help the Blueprint Container pick the right
constructor, method, or parameter arrangement, additional attributes, such as
index or type, can be specified on the argument element. For example, the type
attribute specifies a class name used to match the argument element to a
parameter by the exact type.
Beans
instantiation with constructor
The following example for bean instantiation with
constructor
Java
Class
public class HelloService { public HelloService(long number) { } } |
Blueprint
XML configuration
<bean id=" helloServiceOne" class="com.liferaysavvy.blueprint.HelloService"> <argument value="1"/> </bean> |
Beans
instantiation with factory method.
Bean construction can be happen through the static
factory method as well. We will use bean factory-method attribute so that
Blueprint container identify it and it will instantiate bean by using factory
method.
The following is example for Beans instantiation with
factory method.
Java
Class
public class StaticHelloServiceFactory { public static HelloService createHelloService(long number) { return new HelloService(number); } }
|
Blueprint
XML configuration
<bean id="helloServiceTwo" class="com.liferaysavvy.blueprint.StaticHelloServiceFactory" factory-method="createHelloService"> <argument value="2"/> </bean>
|
Bean
Properties
Blueprint have property tag to provide additional
configuration to the bean and the container will use it whenever bean required.
The following is example to access and declare the
properties for the beans.
Java
class
public class HelloService { public HelloService(long number) { } public String getMessage() { } } |
Blueprint
XML configuration
<bean id="helloServiceOne" class="com.liferaysavvy.blueprint.HelloService"> <argument value="1"/> <property name="message" value="Hi I am Hello Service"/> </bean> |
Bean
Wiring
Sometimes one bean dependence on other bean. We should
wire the bean into the current bean. Property injection is used for wiring
beans together. In the following example, helloServiceOne is injected with a
DependencyService bean.
Java
Classes
public class HelloService { public HelloService() { } public void setDependencyService (Currency currency) { } }
public class DependencyService { public DependencyService () { } } |
Blueprint
XML configuration
<bean id="helloServiceOne" class="com.liferaysavvy.blueprint.HelloService"> <property name="dependencyService" ref="dependencyService" /> </bean> <bean id="dependencyService" class="com.liferaysavvy.blueprint.DependencyService" /> |
Services
Blueprint framework provide the configuration to
register service in OSGi service registry. Blueprint xml have service tag it
will register the declared services. Service implementation will be referred
through ref attribute.
Service
Interface
Service Interface container set of services and its
simple java interface.
public interface HelloService { public String sayHello(); } |
Service
Implementation
Service implementation provided the implementation to
the service interface.
public class HelloServiceImpl implements HelloService { public HelloServiceImpl () { } public void sayHello() { } } |
Blueprint
XML configuration
<service id="helloServiceOne" ref="helloServiceImpl" interface="com.liferaysavvy.blueprint.api.HelloService"/> <bean id="helloServiceImpl" class="com.liferaysavvy.blueprint.impl.HelloServiceImpl"/> |
Without using ref attribute we can also declared
service implementation as inline to the service declaration
<service id="helloServiceTwo" interface="com.liferaysavvy.blueprint.api.HelloService"> <bean class="com.liferaysavvy.blueprint.impl.HelloServiceImpl" /> </service> |
The interfaces under which a service is registered can
be determined by Blueprint using auto-export. The following registers the
service under all the bean's interfaces
<service id="helloServiceOne" ref="helloServiceImpl" auto-export="interfaces" /> <bean id="helloServiceImpl" class="com.liferaysavvy.blueprint.impl.HelloServiceImpl"/> |
Note:
Other values for auto-export are disabled (the
default) class-hierarchy and all-classes.
Service
Properties
We also configure requires properties for the service
using service-properties tag. This service-properties tag contains multiple
entry tags to declared properties and it has key and type as attributes. The
service property values can be of different types, but only OSGi service
property types are permitted: primitives, primitive wrapper classes,
collections, or arrays of primitive types.
The
following is example for property declaration
<service id="helloService" ref="helloServiceImpl" autoExport="all-classes"> <service-properties> <entry key="active"> <value type="java.lang.Boolean">true</value> </entry> <entry key="message" value="say hi"/> </service-properties> </service> |
Service
Ranking
When one service have multiple implementation then
service ranking used to choose the matching service implementation. The default
ranking value is 0. Service ranking is specified using the ranking attributes
as follows:
<service id="serviceFive" ref="account" auto-export="all-classes" ranking="3" /> |
Service
Reference
Services are found in the OSGi service registry using
the reference element from the Blueprint xml file. The following configuration
reference tag referencing the HelloService. If this service found in the OSGi
registry then it will be set in the HelloServiceClient.
Blueprint
Service Reference XML configuration
<bean id="helloworldClient" class="com.liferaysavvy.blueprint.client.HelloServiceClient"> <property name="helloService" ref="helloServiceRef" /> </bean> <reference id="helloServiceRef" interface="com.liferaysavvy.blueprint.api.HelloService"/> |
Blueprint
Implementation Example
Usually OSGi service implementation have their basic bundles.
Service API, Service API Provider and Service Client.
Follow
below articles
Service
API
Service API consist set of services. It means simple
interfaces and its abstract methods. These we will make it as bundle. Usually
we use export mechanism to make these interfaces available to other bundles.
Hello
Service Interface
public interface HelloService { public String sayHello(); } |
Service
API Provider
Service Provider bundle usually implement the services
defined in the Service API bundle.
Hello
Service Implementation
public class HelloServiceImpl implements HelloService { public String sayHello(){ } } |
XML
configuration
<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> <service id="helloServiceOne" ref="helloServiceImpl" interface="com.liferaysavvy.blueprint.api.HelloService"/> <bean id="helloServiceImpl" class="com.liferaysavvy.blueprint.impl.HelloServiceImpl"/> </blueprint> |
Service
Client
Service Client is other bundle, which use the services
provided by Service Provider bundles.
public class HelloServiceClient { HelloService helloService = null; public HelloService getHelloService() { return helloService } public HelloService setHelloService(HelloService helloService) { this.helloService = helloService; } } |
XML configuration
<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> <bean id="helloworldClient" class="com.liferaysavvy.blueprint.client.HelloServiceClient"> <property name="helloService" ref="helloServiceRef" /> </bean> <reference id="helloServiceRef" interface="com.liferaysavvy.blueprint.api.HelloService"/> </blueprint> |
Author
0 comments :
Post a Comment