Complete Guide to Sling Models in Adobe Experience Manager
Complete Guide to Sling Models in Adobe Experience Manager
1. Introduction
In modern AEM development, Sling Models are used to map repository data (JCR nodes or properties) into Java objects. They simplify backend logic and make it easier to expose data to HTL components.
Sling Models follow the Model–View pattern, where:
-
Model → Java class (business logic)
-
View → HTL script
-
Content → JCR repository
Sling Models are part of the Apache Sling framework, which is the core technology behind Adobe Experience Manager.
2. Why Do We Need Sling Models?
Before Sling Models, developers used:
-
JSP scriptlets
-
Use API classes
-
Direct repository access in views
These approaches caused:
❌ Tight coupling
❌ Hard-to-maintain code
❌ Logic inside presentation layer
Sling Models solve this by:
✔ Separating business logic from HTL
✔ Making code reusable
✔ Providing clean dependency injection
✔ Simplifying JCR data mapping
3. Where Exactly Do We Use Sling Models?
Sling Models are mainly used in:
1️⃣ HTL Components
To provide backend logic to HTL templates.
Example component structure:
/apps/project/components/hero
hero.html
HeroModel.java
HTL uses the Sling Model like this:
<div data-sly-use.model="com.project.core.models.HeroModel">
<h1>${model.title}</h1>
</div>
2️⃣ Accessing Component Dialog Data
Component dialog fields store values in the JCR node.
Example JCR structure:
/content/site/page/jcr:content/root/hero
title = "Welcome to AEM"
description = "AEM Sling Model Example"
The Sling Model reads these properties.
3️⃣ Business Logic Layer
Developers also use Sling Models for:
-
Data transformation
-
Service integration
-
API response formatting
4. Basic Sling Model Structure
Example Sling Model:
package com.project.core.models;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;
import org.apache.sling.api.resource.Resource;
@Model(adaptables = Resource.class)
public class HeroModel {
@ValueMapValue
private String title;
@ValueMapValue
private String description;
public String getTitle() {
return title;
}
public String getDescription() {
return description;
}
}
Key points:
| Annotation | Purpose |
|---|---|
@Model | Declares Sling Model |
adaptables | Defines adaptable object |
@ValueMapValue | Injects property from JCR |
5. How Mapping Works Internally
When the HTL script executes:
-
HTL calls the Sling Model
-
AEM adapts the Resource → Sling Model
-
The model reads ValueMap properties
-
Injected values populate fields
Flow:
JCR Node
↓
Resource
↓
Sling Model
↓
HTL
6. Important Injection Annotations
1️⃣ @ValueMapValue
Used to inject properties from the JCR node.
Example:
@ValueMapValue
private String title;
Maps to:
hero
└── title = "Welcome"
2️⃣ @Inject
Generic injector that tries multiple injection sources.
Example:
@Inject
private String title;
Usually replaced with more specific annotations.
3️⃣ @SlingObject
Injects Sling objects.
Example:
@SlingObject
private Resource resource;
@SlingObject
private ResourceResolver resolver;
4️⃣ @OSGiService
Injects OSGi services.
Example:
@OSGiService
private MyService service;
This is used when accessing custom services in **Apache Felix OSGi runtime.
5️⃣ @ChildResource
Used when a component has child nodes.
Example JCR:
hero
└── buttons
└── button1
└── button2
Model:
@ChildResource
private Resource buttons;
6️⃣ @RequestAttribute
Used to inject request attributes.
Example:
@RequestAttribute
private String param;
7. Which Node is Mapping the @Inject?
The mapping depends on adaptable type.
Example:
@Model(adaptables = Resource.class)
Means:
Current component resource
Example resource path:
/content/site/page/jcr:content/root/hero
Properties under this node are injected.
Example mapping:
| JCR Property | Model Field |
|---|---|
| title | title |
| description | description |
8. Sling Model Adaptables
Common adaptables:
Resource
@Model(adaptables = Resource.class)
Reads component content.
SlingHttpServletRequest
@Model(adaptables = SlingHttpServletRequest.class)
Allows access to:
-
request parameters
-
selectors
-
request attributes
Example:
@Model(adaptables = SlingHttpServletRequest.class)
9. Best Practices for Sling Models
✔ Use specific injectors instead of @Inject
✔ Keep models small and focused
✔ Avoid heavy business logic
✔ Use interfaces for models
✔ Use @DefaultInjectionStrategy
Example:
@Model(
adaptables = Resource.class,
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL
)
10. Sling Models vs Use API
| Feature | Sling Models | Use API |
|---|---|---|
| Clean code | Yes | Limited |
| Injection support | Yes | No |
| Recommended | Yes | Deprecated approach |
11. When NOT to Use Sling Models
Avoid Sling Models when:
-
Complex business services
-
Long running operations
-
Heavy data processing
Instead use OSGi services.
12. Conclusion
Sling Models are a fundamental part of modern development in Adobe Experience Manager. They provide a clean way to map repository data to Java objects while keeping the presentation layer simple. By leveraging dependency injection and structured models, developers can build scalable and maintainable AEM components.