March 28, 2020
Estimated Post Reading Time ~

AEM Sling Model

A Sling Model is implemented as an OSGi bundle.

AEM’s component development needs a back end logic to retrieve values from back end. Sightly is a templating language which together with WCMPojo helps to create components.

Adobe recommends Sling Models as a best way of implementing AEM WCM Components from version AEM 6.1.

A Java class located in the OSGi bundle is annotated with @Model and the adaptable class (for example, @Model(adaptables = Resource.class).

The data members (Fields) use @Inject annotations. These data members map to node properties.

In simple terms Sling Models are simple POJO classes which are mapped automatically with Sling Objects (resource, request objects..) and allow us to access jcr node property values directly into java classes.

@PostConstruct annotation can be used to add methods which are invoked upon completion of all injections:

Sample Java Class:

@Model(adaptables = Resource.class) 
public class UserInfo { 
    @Inject 
    private String firstName; 
    
    @Inject 
    private String lastName; 

    public String getFirstName() { 
        return firstName; 
    } 

    public String getLastName() { 
        return lastName; 
    }

    @PostConstruct
    protected void sayHello(){
        logger.info("Hello");
    }
}


Sling model works on injection, once all injections are completed this method (@postconstruct) gets called.



PostConstruct is only used by sling-models. While using WCMUsePojo you have the activate method.

Advantages of using Sling Models

Pure POJO classes.
Entirely annotation driven (Need to write less code).
Can adapt multiple objects – Minimal required Resource and SlingHttpServletRequest OOTB, support resource properties (via ValueMap), SlingBindings, OSGi services, request attributes
Support both classes and interfaces. Plugabble.
Work with existing Sling infrastructure (i.e. not require changes to other bundles).
In order for these classes to be picked up, there is an header which must be added into our bundle's manifest:

<Sling-Model-Packages>
org.apache.sling.models.it.models
</Sling-Model-Packages>


Header must contain all packages which contain model classes or interfaces. However, sub-packages need not be listed individually, e.g. the header in above syntax will also pick up model classes listed in subpackage i.e. org.apache.sling.models.it.models.sub.

Multiple packages can be listed with comma-separated list like below (any white space will be removed):

<Sling-Model-Packages>
org.apache.sling.models.it.models,
org.apache.sling.other.models
</Sling-Model-Packages>

We can also list out all classes individually that are Sling Models classes via the Sling-Model-Classes header.

If we use Sling Models bnd plugin all required bundle headers are generated automatically at build time

Few Sling Annotation Reference
@Model : declares a model class or interface
@Inject : marks a field or method as injectable
@Named : declare a name for the injection (otherwise, defaults based on field or method name).
@Optional : marks a field or method injection as optional
@Source : explicitly tie an injected field or method to a particular injector (by name). Can also be on other annotations.
@Filter : an OSGi service filter
@PostConstruct : methods to call upon model option creation (only for model classes)
@Via : change the adaptable as the source of the injection
@Default : set default values for a field or method
@Path : only used together with the resource-path injector to specify the path of a resource
@Exporter/@Exporters/@ExporterOption/@ExporterOptions : for Exporter Framework
Difference Between WCMUsePojo Vs Sling Models

Mixed POJOs - Pure POJOs
Extends from WCMUsePojo class - Define Standalone class with '@Model' annotation and having no keyword
More code required to retrieve common objects or property values - Easier methods to retrieve common objects or property values
Uses Felix annotation '@Reference' to refer to an available OSGI service - Uses '@Inject' or '@OSGiService'
In the case of WCMUsePojo, we have to overwrite the activate() method - init() method will be called in the @PostConstruct annotation
Not annotation-driven - Annotation driven


By aem4beginner

No comments:

Post a Comment

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