Sunday, December 17, 2017

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


Hi,

I am overwhelmed with a very good response from my previous blogs over sling model and
when i am really going more in deep of this concept, there are a lot of things which can ovewhelm you more.

Our journey of Sling Models is not over yet and we have something really interesting to know more.

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
Demonstration Video On Registration of Sling Model Via Bnd Plugin:

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.

res.PNG

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
request.PNG
  • 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";
  }
}

Let’s demo it for an amazing understanding:


If you have any query or suggestion then kindly comment or mail us at sgaem.blog02@gmail.com

Hope it will help you guys !!
Thanks and Happy Learning.

3 comments:

  1. Caching from request has been removed in SP2 CFP1 due to memory consumption issues. https://helpx.adobe.com/experience-manager/release-notes--aem-6-3-cumulative-fix-pack.html

    ReplyDelete
  2. Nice article for Sling Model information.

    Also found one more article for Adobe AEM with defined information

    https://aemintroduction.blogspot.com/


    ReplyDelete