March 29, 2020
Estimated Post Reading Time ~

Deep Dive in Sling Models in AEM 6.3 : Part-3

Registration of Sling Models Via Bnd Plugin (Since Sling Model Impl 1.3.4)

When creating sling Models, there is an important step of adding the sling Model package in maven-bundle plugin. This plugin generates Sling-Model Classes header.

Now through bnd plugin you can get rid of adding <Sling-Model package> in maven-bundle-plugin.

You just neet to add <_plugin>org.apache.sling.bnd.models.ModelsScannerPlugin</_plugin> in the configuration tag.

<plugin>
<groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <extensions>true</extensions>
<configuration> <instructions> <_plugin>org.apache.sling.bnd.models.ModelsScannerPlugin</_plugin> </instructions>
</configuration>
<dependencies> <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.bnd.models</artifactId> <version>1.0.0</version> </dependency>
</dependencies>
</plugin>


This will scan all the Sling Models by itself. If Sling Model package or Sling model Classes are already manually defined,bnd plugin will not work.

Note: Don't define Sling model package manually if you are using bnd plugin.

If you want to generate a bundle header compliant with Sling Models < 1.3.4 (i.e. Sling-Model-Packages) you need to specify the attribute generatePackagesHeader=true. An example configuration looks like this

<configuration>
<instructions> <_plugin>org.apache.sling.bnd.models.ModelsScannerPlugin;generatePackagesHeader=true</_plugin>
</instructions>
</configuration>


Caching

By default, Sling Models don’t have any caching of the adaption result.There was a big problem that adaption of every request for a model class will create a new instance of that model.

There are two cases when the adaption results can be cached.

The first case is when the adaptable extends SlingAdaptable base class.This case is for the resources adaptables as AbstractResource extends SlingAdaptable.

Sling Adaptable has a caching mechanism such that when we do multiple time adaption (adaptTo)of same resource will return the same object.


By default two objects of same sling models adapted from a resource are same.

TestModel testModel1 = resource.adaptTo(TestModel.class);
TestModel testModel2 = resource.adaptTo(TestModel.class);

Assert testModel1 == testModel2 



This is notably not in the case of SlingHttpServletRequest as this class doesn’t extend SlingAdaptable.

By default two objects of same sling models, adapted from a request are false.

TestModelRequest testModelRequest1 = request.adaptTo(TestModelRequest.class);
TestModelRequest testModelRequest2 = request.adaptTo(TestModelRequest.class);

Assert testModelRequest1 == testModelRequest2


Since Sling Models API version 1.3.4 , Sling Models can cache adaptable results regardless of the adaptable by specifying cache=true in @Model annotation.

If we put the TestModelRequest Sling Model like this:
@Model(adaptables = SlingHttpServletRequest.class,cache = true)
public class TestModelRequest {

TestModelRequest testModelRequest1 = request.adaptTo(TestModelRequest.class);
TestModelRequest testModelRequest2 = request.adaptTo(TestModelRequest.class);

Assert testModelRequest1 == testModelRequest2
}

Note: When cache = true is specified, the adaptation result is cached regardless of how the adaptation is done. Read more about Sling Adaption Framework .

Specifying an Alternative Adapter Class(Since Sling Model Impl 1.1.0)

By default a Sling Model is registered with its own implementations.But @Model annotation also has an attribute named adapters which allows specifying under which type(s) the model implementation should be registered in the Models Adapter Factory. Prior to Sling Models Impl 1.3.10 only the given class names are used as adapter classes, since 1.3.10 the implementation class is always being registered implicitly as adapter as well.

With this attribute it is possible to register the model to one (or multiple) interfaces, or a superclass. This allows separating the model interface from the implementation, which makes it easier to provide mock implementations for unit tests as well.

public interface A{
public String getName();
}
public interface B{
public String getPath();
}

@Model(adaptables = Resource.class, adapters = {A.class, B.class})
public class TestAdapter implements A, B {
// injects fields and implements the A and B interface's methods
public String getName() {
return "SGAEM";
}

public String getPath() {
return "sgaem.blogspot.in";
}
}


By aem4beginner

No comments:

Post a Comment

If you have any doubts or questions, please let us know.