In AEM (Adobe Experience Manager), OSGi (Open Service Gateway Initiative) Factory configurations can be used to create multiple instances of the same OSGi component, each with its own set of configuration properties.
Here’s how to create an OSGi Factory configuration in AEM:
1. Define the OSGi component
Create an OSGi component that will be instantiated as a factory service. For example:
package com.example.service.impl; import org.osgi.service.cm.ConfigurationException; import org.osgi.service.cm.ManagedService; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; @Component(service = ManagedService.class, factory = "myService.factory") public class MyService implements ManagedService { private String myProperty; @Override public void updated(Dictionary<String, ?> properties) throws ConfigurationException { if (properties != null) { myProperty = (String) properties.get("myProperty"); } } public String getMyProperty() { return myProperty; } @Reference private ConfigurationAdmin configAdmin; }
In this example, we use the @Component
annotation to define the MyService
class as an OSGi component. The factory
attribute is set to myService.factory
to indicate that this component should be instantiated as a factory service.
2. Define the configuration definition
Create a configuration definition class that defines the configuration properties for the factory. For example:
package com.example.service.impl; import org.osgi.service.metatype.annotations.AttributeDefinition; import org.osgi.service.metatype.annotations.ObjectClassDefinition; @ObjectClassDefinition(name = "My Service Configuration Factory", description = "Configuration for My Service Factory") public @interface MyServiceFactoryConfiguration { @AttributeDefinition(name = "My Property", description = "A custom property") String myProperty() default "default value"; }
In this example, we use the @ObjectClassDefinition
annotation to define the configuration definition for the MyService
factory. The name
and description
attributes provide metadata for the configuration definition. We also define a single configuration property using the @AttributeDefinition
annotation.
3. Implement the factory service
Create an implementation class for the factory service that creates instances of the OSGi component. For example:
package com.example.service.impl; import java.util.Dictionary; import java.util.HashMap; import java.util.Map; import org.osgi.service.cm.ConfigurationException; import org.osgi.service.cm.ConfigurationAdmin; import org.osgi.service.cm.ManagedServiceFactory; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; @Component(service = ManagedServiceFactory.class, name = "myService.factory") public class MyServiceFactory implements ManagedServiceFactory { private final Map<String, MyService> services = new HashMap<>(); @Override public String getName() { return "My Service Factory"; } @Override public void updated(String pid, Dictionary<String, ?> properties) throws ConfigurationException { MyService service = services.get(pid); if (service != null) { service.updated(properties); } else { MyService newService = new MyService(); newService.updated(properties); services.put(pid, newService); } } @Override public void deleted(String pid) { services.remove(pid); } @Reference private ConfigurationAdmin configAdmin; }
In this example, we use the @Component
annotation to define the MyServiceFactory
class as a factory service. The name
attribute is set to myService.factory
to match the factory
attribute in the @Component
annotation of the MyService.