Expand my Community achievements bar.

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.