I love writing code. What I love more is writing less. That is why I like Sling models. I have written about leveraging its injectors. And how to create custom ones. Now I will cover the @Via annotation, the OOTB providers, and how to create custom ones.
What @Via Does
Sling relies heavily on the adapter pattern. This is the pattern used by the Sling model framework. The "adaptable" is the thing that will adapt to an instance of that model. This more often than not is a Resource or SlingHttpServletRequest. But it is not limited to these.
The Sling model injection will look into the adaptable and try to resolve the value it needs to inject. For example, see the @ValueMapValue annotation and its injector.
What @Via does is swap out the original adaptable for something else. The ModelAdapterFactory will use the new adaptable from that point on.
So what are some potential use-cases?
⚠️ In the following examples I am using Groovy to implement the models and OSGi components. I am also using Spock to write unit tests. If you are using Java, these examples are easily translated into Java. If you are interested in Groovy & Spock, read my other articles.
Making AEM Groovy Without the Console
AEM Unit Testing With Groovy & Spock
Extending Core Components with Sling Delegation
The correct way to customize the sling model of a core component is with the delegation pattern. Interview answer 😉.
Let's take for example the Button component. There are 2 versions of this. V2 ButtonImpl extends V1. Those are internal implementation classes. I can not extend them in my own project because I do not have visibility into them. I have to use @Via and specify the ResourceSuperTypeViaProvider. First, in a TDD fashion, let's write some unit tests.