Skip to main content

OSGI Component and Services


Component are those classes which are marked with @Component annotation and whose life cycle is managed by felix.  A component is an active participant in the OSGi system , a component can be reinitialized through osgi properties through the methods annotated in the class using the activate and deactivate methods. In order to mark class as component in  aem ecosystem provide @component annotation provided through java package "org.apache.felix.scr.annotations.Component".Please refer the example below.
Code sample are for illustration purpose only
Following are annotation used are some of basic annotation which should always be used while you are creating component.
@label-This is generally used as a title for the object described by the meta type.
@description-This is generally used as a description for the object described by the meta type.
@metatype-If marked as true it will create a metatype.xml within meta type folder in meta-inf folder in bundle and also it will does a look for the osgi property which is being provided using the property annotation.
@immediate - If marked true will be initialized immediately, if marked as false then the component will check if component is marked as servicefactory which will be covered later in this article.

Let's say you have developed a reusable component and now you want refer the same in another component , so we have only one option , create a new instance of class you want to refer using the new keyword , but that is a serious crime as you are are statically binding a class which is not at all a good design principle. So you can refer another component by converting a component to service using @Service annotation and you can refer the same using@Reference annotation.Just like Spring framework and Google’s Guice it is possible to use dependency injection in AEM in order to acquire a reference to one or more services.

Let's let's see a very basic example of how to make  convert a component to service.Once you have marked component with service annotation it get's registered as a service in osgi ecosystem and you can refer service from   another component using the reference annotation.

Code snippet are for illustration purpose only
Code snippet for illustration purpose

The modified code for Test Component which now refers the Test Service is as shown below line number 30.

Code snippet are for illustration purpose

Sometimes you need to implement services, which just differ by configuration. A nice example for this is the logging, where you want to have the possibility to have multiple logging facilities being logged to log files at a different level. Somebody (normally the admin of the system) is then able to leverage this and configure the logging as she likes.

So more formally spoken you have zero to N instances of the same service, but just with different configuration. Just duplicating the code and create a logger1 with configurable values, a logger2, logger3 and so doesn’t make sense, as it’s just code duplication and inflexible .

OSGI offers for this kind of problem with the concept of Service Factories. As the name already says, it’s a factory to create services, just by configuration.
So let's modify the TestServiceImpl referred above to make it as service factory, it quite easy just add the configurationFactory=true in @Component annotation.
Code snippet for illustration purpose only
The modified TestServiceImpl looks like below.



If you compile and deploy your service now, you can see in your Apache Felix Configuration Manager, that you have a “plus” sign in front of the service; and when you click it, you get a new instance of your service, which you can configure.


But when you have 3 services configured which one do you get when you have something like this:


The answer: It’s not deterministic. You might get any of the configured testservices. If you need a special one, the easiest way is to provide labels for them to make them unique. So add another property to your service:



This will resolve correctly when you have a testservice configured with the name“TestService”. As long as you don’t have such a service, any service containing such a reference won’t start.

Please leave any comments or feed back ,if you have any question



Comments

Popular posts from this blog

Handle bar & AEM server side integration

In AEM 6.0 version, as part of social communities’ project AEM implemented a handlebar script files in place of JSP scripts.  As part of this project AEM SCF community implemented a handle bar engine which in turn uses handlebars.java(jknack) library to compile and execute handlebar templates. Example: Let’s say I have a component called helloworld and the path of component  is  /apps/mysite/components/content/helloworld. Below three steps we need to do to implement header component. 1.       Register a HBS component To register HBS component we need to implement SocialComponentFactory interface and then we need to override methods. In “getSupportedResourceType” method we need to return component path to register it to handlebar engine.  Once we register a component json response will automatically available to handlebar script file. Example: The key aspect is to override getSocialComponent method(Resource).

How to remove hardcoding .html from pathfield in AEM/CQ

In our project we have a pathfield in quite a lot of dialog for various custom components which refers/links to pages. After getting the value of this pathfield in the sightly template we were  adding the html extension manually on it. e.g.                 <a class="navbar-brand" href="${properties.homepagePath @ context='unsafe'}">${properties.headerAuthTitle}</a> We can avoid hardcoding the path by adding property in dialog link  linkPattern The  pathfield  xtype has a config option called  linkpattern . This allows you to configure the widget to automatically add an extension  in case the browsefield is used  to select the link. If a user types the text , the extension is not added. Use this option to add '.html' and all internal links will have .html appended (assuming the content authors always use the pathfield's browse option to select the link [which they should be doing ] ). This way the backend code doesn't hav

Proxy Design Pattern

We use this Pattern when we require don't want to give a direct access to object under some scenario and rather offer a surrogate object  or proxy object which  provides the functionality in place of the real object. There could be several scenario where we would want this kind of functionality. The  real object  has some sensitive operation which would be risky to expose. The real object creation is memory extensive so we want to control the behavior of its creation. The real object is remotely located and rather we want to interact through a local copy using proxy which is actually   aware of it location. So lets look at the UML diagram of the same. So here we have Subject interface which is implemented by both the Proxy and RealObject  and proxy object has  reference to the real object , now the client will  instantiate Proxy object to perform some action and , proxy object will delegate the call to RealSubject to perform the same.