There are two ways to do this. The first approach would be preferable
Selective activation via Configuration
You can achieve that by using Sling Run Mode based Configuration support and using Declarative Services for managing service registration.
Bind your service to Configuration
Use SCR annotation to bind your service to configuration
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.ConfigurationPolicy;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
@Component(
name = FooImpl.SERVICE_PID,
policy = ConfigurationPolicy.REQUIRE)
@Service
public class FooImpl implements IFoo{
public static final String SERVICE_PID = "com.foo.example";
In above code snippet we
- Register a service which implements
IFoo
interface
ConfigurationPolicy
for the component is set to REQUIRE
i.e. without any explicit configuration the component and thus the service would not be activated and registered
- The PID of the config is set to
com.foo.example
. If you omit it then it default to fully qualified name of the class
Create config under the required Run Mode folder
In CQ the Sling installer would deploy configuration and bundle from the repository based on the Run Mode. So if you are deploying your code via Content Packages then
- Create a config node under path
/apps/<yourProject>/config.author/com.foo.example
- Under above path just create a blank ode (unless you want to provide other config properties) of type
sling:OsgiConfig
With above changes done deploy your content package on various CQ instances
- When package is deploy on any CQ instance then Configuration for PID
com.foo.example
would only be created when the run mode is set to Author
- And only when configuration is active then only
FooImpl
component and service would be created and registered
Using SlingSettingsService
Another approach can make use of the SlingSettingsService.getRunModes to determine the run mode programatically and then only register the service.
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
@Component
public class FooImpl implements IFoo{
@Reference
private SlingSettingsService settingsService;
private ServiceRegistration reg;
@Activate
public void activate(BundleContext context, Map<String, ?> conf){
if(settingsService.getRunModes().contains("author")){
reg = context.registerService(IFoo.class.getName(), this, null);
}
}
@Deactivate
private void deactivate(){
if (reg != null){
reg.unregister();
}
}
}
Couple of points to note for above snippet
FooImpl
is not annotated with @Service
tag. So SCR would only activate the component but would not register any service
- In
activate
method we use SlingSettingsService
to check for required run mode. In case it is author
we programatically register the service
- Service instance is removed later in the
deactivate
method