Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.
SOLVED

What is the difference between @Inject and @ValueMapValue in simple words.

Avatar

Level 2
 
1 Accepted Solution

Avatar

Correct answer by
Community Advisor

The injected fields are normally the properties of a component (which the content authors normally set via component dialog). 

@inject:

@Model(adaptables=Resource.class)
public class MyModel {

    @Inject
    private String propertyName;
}

In this case, a property named "propertyName" will be looked up from the Resource (after first adapting it to a ValueMap) and it is injected.

Avoid @Inject. Value injection happens at runtime. If you use @inject then you are making the framework do extra guesswork. It would be good if we use  injector annotations like @ValueMapValue, @childResource

Value Map (name=”valuemap”) Injector

Gets a property from a ValueMap by name; If @Via is not set, it will automatically take resource if the adaptable is the SlingHttpServletRequest. If name is not set the name is derived from the method/field name.

 

@Model(adaptables = SlingHttpServletRequest.class,
    defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class ExampleComponent {

    // @Inject @Source("valuemap") @Named("jcr:title")
    @ValueMapValue(name = "jcr:title")
    private String titleText;

    // @Inject @Source("valuemap")
    @ValueMapValue
    private String titleDescription;

It means if we use @@ValueMapValue it will be done automatically an we have to write less code.

 

 

 

Refer here-https://sling.apache.org/documentation/bundles/models.html

https://sourcedcode.com/blog/aem/aem-sling-model-injectors-annotations-cheat-sheet-reference-guide#V...

 

 

View solution in original post

5 Replies

Avatar

Community Advisor

Please refer below example to get property value when Model is created using SlingHttpServletRequest as an Adaptable and we have to add @Via to get property from current resource.

@Model(adaptables=SlingHttpServletRequest.class)
public interface MyModel {
 //will return request.getResource().getValueMap().get("propertyName", String.class)
    @Inject @Via("resource")
    String getPropertyName();
} 

whereas if you use @ValueMapValue it will be done automatically and you have to write less code. Refer this snippet from Sling Document :
@ValueMapValue : Injects a ValueMap value. If via is not set, it will automatically take resource if the adaptable is the SlingHttpServletRequest. If name is not set the name is derived from the method/field name.

Link : https://sling.apache.org/documentation/bundles/models.html

Avatar

Correct answer by
Community Advisor

The injected fields are normally the properties of a component (which the content authors normally set via component dialog). 

@inject:

@Model(adaptables=Resource.class)
public class MyModel {

    @Inject
    private String propertyName;
}

In this case, a property named "propertyName" will be looked up from the Resource (after first adapting it to a ValueMap) and it is injected.

Avoid @Inject. Value injection happens at runtime. If you use @inject then you are making the framework do extra guesswork. It would be good if we use  injector annotations like @ValueMapValue, @childResource

Value Map (name=”valuemap”) Injector

Gets a property from a ValueMap by name; If @Via is not set, it will automatically take resource if the adaptable is the SlingHttpServletRequest. If name is not set the name is derived from the method/field name.

 

@Model(adaptables = SlingHttpServletRequest.class,
    defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class ExampleComponent {

    // @Inject @Source("valuemap") @Named("jcr:title")
    @ValueMapValue(name = "jcr:title")
    private String titleText;

    // @Inject @Source("valuemap")
    @ValueMapValue
    private String titleDescription;

It means if we use @@ValueMapValue it will be done automatically an we have to write less code.

 

 

 

Refer here-https://sling.apache.org/documentation/bundles/models.html

https://sourcedcode.com/blog/aem/aem-sling-model-injectors-annotations-cheat-sheet-reference-guide#V...

 

 

Avatar

Employee Advisor

@Inject: This annotation is used to inject a property, resource, request, OSGi service.

               This is a generic annotation

 

@ValueMapValue: Injects a ValueMap value. If via is not set, it will automatically take resource if the adaptable is the SlingHttpServletRequest. If name is not set the name is derived from the method/field name.

 

DEBAL_DAS_0-1660038154718.png

 

 

 

Avatar

Level 1
Level 1

It might look similar, but they are not the same, @inject is a general-purpose annotation that makes the value available from a number of injectors.

@ValueMapValue is an injector specific annotation that will specifically pick value from valuemap injector. It is equivalent to @inject @source("valuemap")

When the injected value is available only from one injector, their behavior would be the same, however if the same property is provided by two different injectors (say script-binding and valuemap) they might inject different values.

Avatar

Level 2

@inject- used to inject OSGi Services or Sling object into a Java class.
Sling objects- Resource, Session, ValueMap, SlingHttpServletRequest, etc.,

@ValueMapValue - used to inject properties of a resource (node) that are stored in the JCR repo.
Such as title of a page, description of an image etc.,

@Inject has some major issues, hence it is not recommended for use.
Instead of using @Inject, it is recommended to use dependency injection frameworks like OSGi Declarative Services (DS) or the Sling Models Dependency Injection framework.