AEM is based on OSGI, which itself is largely structured around the concepts of service providers and consumers. A service provider in OSGI is a body of code that promises to do something on your behalf. A consumer of that service is a piece of code (also called the client) that uses the services offered by the provider to achieve its own goals. In that sense, it is comparable to the service providers and consumers in our general, non-technical lives.
A service provider is a special kind of code, which actually provides the implementation of these interfaces. In other words, a service provider contains the ‘actionable’ code which executes the promises made by the interfaces it (the service provider) represents.
In the AEM multiverse, defining services (or interfaces) and their decoupled providers form a large body of the code. Most code developers who write against AEM involve the need to use interfaces, or services, that AEM provides for our use. This can range from a service that promises to send emails, to low-level services that promise to write content in a concurrent-safe manner. One of the best things we get out of using a mature framework such as AEM, is that these services (and their implementations) are already provided to us.
Using Client-code for AEM Services
The rest of this blog is going to focus on how to get a handle on these services in our own code (also called the client-code, or simply the client).
For this example, consider an interface that is defined as:
And a service implementation that is defined as:
Getting a Service Implementation Using the ‘SlingScriptHelper’ Object
Now consider a use-case where this is used in a regular Java class that serves as a back-end model for a JSP page. A backing model is simply a regular Java class which can be used to include all the Java-code in a regular Java class as opposed to dumping it in the JSP file. This Java class is the client in this scenario, and attempts to use the email service available in the code.
Notice that a handle to the service-provider is made by using a SlingScriptHelper object provided by the AEM framework:
In the JSP file itself, the client code looks like this:
Accessing a Service Using a ‘Sling Model’
The second, and my favorite method of obtaining services in AEM is by using sling models. A ‘Sling Model’ is a special kind of class whose life-cycle processes are managed by the container (in this case AEM) itself. In the larger programming world, such container-managed classes are also called ‘beans’, or simply a container-managed entity. The details of this topic are quite technical, but these entities are defined by using suitable annotations. In this case, the annotation @Model converts the following class into a ‘sling-model’.
The client code (in the JSP) looks like this:
Using services to augment your code-base is generally a very good practice. It allows the client-code to remain completely free from the details of how the services are implemented in each provider. In this blog, we discussed a few ways in which you can use service providers from your client-code. In the next blog, we will see how to take advantage of services in even more ways, some of which involve very low-level programming interfaces.