Expand my Community achievements bar.

SOLVED

Sling Models Custom Injector Precedence Order

Avatar

Former Community Member

I have created a custom Sling Models injector. It's deployed as an OSGi service and works successfully but I have a problem.

The immediate question I have relates to the precedence order in which the injectors are called. I set my injector to have service ranking of 9999 so that it would likely only be called if I declared it explicitly with the @Source annotation, or so I thought. In reality it gets called for ALLmethods/fields unless I set them explicitly too e.g. to stop my custom injector being called I may set @Source("valuemap"). I suspect this is because my injector isn't registered properly or the configuration is awry. Obviously I'd like to ONLY have to specify my injector for those methods/fields that need it and leave all others to follow the default behavior, but I don't know how to do that.

Can someone help ?

Regards

Fraser

1 Accepted Solution

Avatar

Correct answer by
Employee

It's under the Status dropdown in the Web Console. Direct URL would be something like http://localhost:4502/system/console/status-slingmodels.

In your injector, you can inspect the AnnotatedElement passed to it. Take a look at the sample code here: https://github.com/justinedelson/sling-models-demo/blob/master/src/main/java/com/adobe/people/jedels... (which is the same code as on Slide 31 of my AEM Hub presentation).

View solution in original post

6 Replies

Avatar

Employee

Fraser-

Does the output of the Sling Models Configuration Printer show your injector coming in last? That would be the best way to check that the configuration was correct.

Note that even if it is last, your injector may still be invoked for methods/fields which don't have a specific @Source injector if, for example, no other inejctor can handle that method/field. If your injector wants to require the use of the @Source annotation, you would need to deal with that in the injector itself by returning null early.

Regards,

Justin

Avatar

Former Community Member

Hey Justin,

where do I check for the Sling Models Configuration Printer output  ?

re: custom injector *could* still be called ... Agreed ... can the value of the @Source annotation be accessed from within the injector ?

Regards

Fraser.

Avatar

Correct answer by
Employee

It's under the Status dropdown in the Web Console. Direct URL would be something like http://localhost:4502/system/console/status-slingmodels.

In your injector, you can inspect the AnnotatedElement passed to it. Take a look at the sample code here: https://github.com/justinedelson/sling-models-demo/blob/master/src/main/java/com/adobe/people/jedels... (which is the same code as on Slide 31 of my AEM Hub presentation).

Avatar

Former Community Member

Thanks Justin.

It looks as though my injector is correctly registered as it appeared last in the list in the Sling Models console.

I added this check in my injector to cause it to fail-fast if called by a field/method that is not explicitly annotated with the name of my injector :-

/** * Check that the call to this injector has ONLY come from a method/field that has a * @Source annotation value that corresponds to THIS injectors name */ Source src = element.getAnnotation(Source.class); if (src != null){ String srcValue = src.value(); log.info("Source annotation is (" + srcValue + ")"); if (!srcValue.equals(injectorName)){ log.info("This injector ONLY processes calls that explicitly declare a @Source annotation value of (" + injectorName + ")"); return null; } else { log.info("The @Source annotation value is correct for THIS injector."); } } else { log.info("No @Source annotation is present on the calling method/field. This injector ONLY processes calls that explicitly declare a value of (" + injectorName + ")"); return null; }

Seems to work OK and means I don't need to explictly state the @Source annotations on all the field/methods that I am not dealing with (i.e. I am expecting one of the other to do so).

Can you confirm (or not) a couple of things for me please :-

  1. Do ALL of the injectors get called if NO @Source annotation is declared for the field/method ?
  2. If a @Source annotation value IS declared, ONLY that injector gets called ?
  3. An injector indicates that it can't deal with a request by returning NULL ?
  4. What happens if 2 or more injectors try and deal with a request ?

Regards

Fraser.

Avatar

Employee

Hi,

> Do ALL of the injectors get called if NO @Source annotation is declared for the field/method ?

Yes, at least until one of the injectors returns a non-null value, at which point no other injectors will be called for that field/method.

> If a @Source annotation value IS declared, ONLY that injector gets called ?

Yes.

> An injector indicates that it can't deal with a request by returning NULL ?

Yes.

> What happens if 2 or more injectors try and deal with a request ?

I'm not sure what you mean by "try and deal with a request". Could you clarify?

Regards,

Justin

Avatar

Former Community Member

> I'm not sure what you mean by "try and deal with a request". Could you clarify?

You already answered that for me in the reply to (1) '... until one of the injectors returns a non-null value, at which point no other injectors will be called', i.e. a situation where a second injector tries to deal with a method/field that an earlier injector already processed can't happen.

Thanks

Fraser.