In AEM (Adobe Experience Manager), OSGi (Open Service Gateway Initiative) services can be filtered and targeted based on specific criteria using the @Reference
annotation. This allows you to specify which implementation of a service to use when multiple implementations are available in the OSGi container.
Here is an example of using filters and targets with the @Reference
annotation:
1. Create an OSGi service interface
This interface defines the methods that the OSGi service will provide. For example:
package com.example.service; public interface MyService { String getMessage(); }
2. Create multiple implementations of the OSGi service interface
These classes provide different implementations of the methods defined in the OSGi service interface. For example:
package com.example.service.impl; import com.example.service.MyService; import org.osgi.service.component.annotations.Component; @Component(service = MyService.class, property = { "message=impl1" }) public class MyServiceImpl1 implements MyService { @Override public String getMessage() { return "Hello from implementation 1!"; } }
package com.example.service.impl; import com.example.service.MyService; import org.osgi.service.component.annotations.Component; @Component(service = MyService.class, property = { "message=impl2" }) public class MyServiceImpl2 implements MyService { @Override public String getMessage() { return "Hello from implementation 2!"; } }
In this example, we have created two implementations of the MyService
interface, and have used the @Component
annotation to mark them as OSGi components. The property
attribute in the @Component
annotation is used to specify a custom property that identifies each implementation.
3. Filter and target the OSGi service
To filter and target the OSGi service based on the custom properties, use the @Reference
annotation with the filter
and target
attributes. For example:
package com.example.servlets; import com.example.service.MyService; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; @Component(service = Servlet.class, property = { "sling.servlet.paths=/bin/my-servlet" }) public class MyServlet extends SlingSafeMethodsServlet { @Reference(filter = "(message=impl1)", target = "(service.pid=com.example.service.impl.MyServiceImpl1)") private MyService myService; @Override protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException { response.getWriter().write(myService.getMessage()); } }
In this example, the MyServlet
class injects the MyService
instance using the @Reference
annotation, and filters and targets the implementation using the filter
and target
attributes. The filter
attribute specifies the custom property used to identify the implementation, and the target
attribute specifies the OSGi service PID (persistent identifier) of the implementation.
That’s it! You have now used filters and targets to specify which implementation of an OSGi service to use in AEM.