You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2019/10/30 04:31:46 UTC

[james-project] 02/07: JAMES-2938 Rely more on InitilizationOperationBuilder

This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit be9711eba7040e848304f55d5ec03dfbf9d77a40
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Tue Oct 29 13:07:56 2019 +0700

    JAMES-2938 Rely more on InitilizationOperationBuilder
---
 metrics/metrics-dropwizard/pom.xml                 |  4 +
 .../metrics/dropwizard/DropWizardJVMMetrics.java   |  4 +-
 .../dropwizard/DropWizardMetricFactory.java        |  3 +-
 .../modules/data/CassandraDomainListModule.java    | 30 ++------
 .../data/CassandraRecipientRewriteTableModule.java | 33 ++------
 .../data/CassandraUsersRepositoryModule.java       | 34 ++------
 .../mailbox/ElasticSearchMailboxModule.java        | 32 +++-----
 .../mailbox/ElasticSearchQuotaSearcherModule.java  | 32 +++-----
 .../modules/metrics/CassandraMetricsModule.java    | 38 +++------
 .../james/data/LdapUsersRepositoryModule.java      | 37 +++------
 .../modules/event/RabbitMQEventBusModule.java      | 29 ++-----
 .../server/ElasticSearchMetricReporterModule.java  | 34 ++------
 .../james/modules/server/DNSServiceModule.java     | 38 +++------
 .../modules/server/DropWizardMetricsModule.java    | 39 ++++------
 .../modules/server/MailStoreRepositoryModule.java  | 30 ++------
 .../james/modules/server/JMXServerModule.java      | 82 ++++++--------------
 .../james/modules/data/JPADomainListModule.java    | 32 ++------
 .../data/JPARecipientRewriteTableModule.java       | 34 ++------
 .../modules/data/JPAUsersRepositoryModule.java     | 34 ++------
 .../james/modules/mailbox/DefaultEventModule.java  | 32 ++------
 .../modules/server/CamelMailetContainerModule.java | 90 ++++++++--------------
 .../james/modules/data/MemoryDataModule.java       | 59 +++-----------
 .../james/modules/protocols/IMAPServerModule.java  | 35 +++------
 .../modules/protocols/JMAPDraftServerModule.java   | 49 ++++--------
 .../james/modules/protocols/LMTPServerModule.java  | 38 +++------
 .../modules/protocols/ManageSieveServerModule.java | 35 +++------
 .../james/modules/protocols/POP3ServerModule.java  | 37 +++------
 .../james/modules/protocols/SMTPServerModule.java  | 39 +++-------
 .../james/modules/server/WebAdminServerModule.java | 29 ++-----
 29 files changed, 282 insertions(+), 760 deletions(-)

diff --git a/metrics/metrics-dropwizard/pom.xml b/metrics/metrics-dropwizard/pom.xml
index 20e2423..9670a16 100644
--- a/metrics/metrics-dropwizard/pom.xml
+++ b/metrics/metrics-dropwizard/pom.xml
@@ -36,6 +36,10 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>james-server-lifecycle-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>testing-base</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/metrics/metrics-dropwizard/src/main/java/org/apache/james/metrics/dropwizard/DropWizardJVMMetrics.java b/metrics/metrics-dropwizard/src/main/java/org/apache/james/metrics/dropwizard/DropWizardJVMMetrics.java
index 2312081..be5ea5b 100644
--- a/metrics/metrics-dropwizard/src/main/java/org/apache/james/metrics/dropwizard/DropWizardJVMMetrics.java
+++ b/metrics/metrics-dropwizard/src/main/java/org/apache/james/metrics/dropwizard/DropWizardJVMMetrics.java
@@ -21,6 +21,8 @@ package org.apache.james.metrics.dropwizard;
 
 import javax.inject.Inject;
 
+import org.apache.james.lifecycle.api.Startable;
+
 import com.codahale.metrics.MetricRegistry;
 import com.codahale.metrics.jvm.ClassLoadingGaugeSet;
 import com.codahale.metrics.jvm.FileDescriptorRatioGauge;
@@ -28,7 +30,7 @@ import com.codahale.metrics.jvm.GarbageCollectorMetricSet;
 import com.codahale.metrics.jvm.MemoryUsageGaugeSet;
 import com.codahale.metrics.jvm.ThreadStatesGaugeSet;
 
-public class DropWizardJVMMetrics {
+public class DropWizardJVMMetrics implements Startable {
 
     private final MetricRegistry metricRegistry;
 
diff --git a/metrics/metrics-dropwizard/src/main/java/org/apache/james/metrics/dropwizard/DropWizardMetricFactory.java b/metrics/metrics-dropwizard/src/main/java/org/apache/james/metrics/dropwizard/DropWizardMetricFactory.java
index 03a9591..015c21d 100644
--- a/metrics/metrics-dropwizard/src/main/java/org/apache/james/metrics/dropwizard/DropWizardMetricFactory.java
+++ b/metrics/metrics-dropwizard/src/main/java/org/apache/james/metrics/dropwizard/DropWizardMetricFactory.java
@@ -23,6 +23,7 @@ import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
 import javax.inject.Inject;
 
+import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.metrics.api.Metric;
 import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.metrics.api.TimeMetric;
@@ -30,7 +31,7 @@ import org.apache.james.metrics.api.TimeMetric;
 import com.codahale.metrics.MetricRegistry;
 import com.codahale.metrics.jmx.JmxReporter;
 
-public class DropWizardMetricFactory implements MetricFactory {
+public class DropWizardMetricFactory implements MetricFactory, Startable {
 
     private final MetricRegistry metricRegistry;
     private final JmxReporter jmxReporter;
diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraDomainListModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraDomainListModule.java
index 82ad33f..578d745 100644
--- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraDomainListModule.java
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraDomainListModule.java
@@ -23,16 +23,16 @@ import org.apache.james.backends.cassandra.components.CassandraModule;
 import org.apache.james.domainlist.api.DomainList;
 import org.apache.james.domainlist.cassandra.CassandraDomainList;
 import org.apache.james.domainlist.lib.DomainListConfiguration;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Provides;
 import com.google.inject.Scopes;
 import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class CassandraDomainListModule extends AbstractModule {
 
@@ -41,7 +41,6 @@ public class CassandraDomainListModule extends AbstractModule {
         bind(CassandraDomainList.class).in(Scopes.SINGLETON);
         bind(DomainList.class).to(CassandraDomainList.class);
         Multibinder.newSetBinder(binder(), CassandraModule.class).addBinding().toInstance(org.apache.james.domainlist.cassandra.CassandraDomainListModule.MODULE);
-        Multibinder.newSetBinder(binder(), InitializationOperation.class).addBinding().to(CassandraDomainListInitializationOperation.class);
     }
 
     @Provides
@@ -53,26 +52,11 @@ public class CassandraDomainListModule extends AbstractModule {
             throw new RuntimeException(e);
         }
     }
-    
-    @Singleton
-    public static class CassandraDomainListInitializationOperation implements InitializationOperation {
-        private final DomainListConfiguration configuration;
-        private final CassandraDomainList cassandraDomainList;
-
-        @Inject
-        public CassandraDomainListInitializationOperation(DomainListConfiguration configuration, CassandraDomainList cassandraDomainList) {
-            this.configuration = configuration;
-            this.cassandraDomainList = cassandraDomainList;
-        }
 
-        @Override
-        public void initModule() throws Exception {
-            cassandraDomainList.configure(configuration);
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return CassandraDomainList.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation configureDomainList(DomainListConfiguration configuration, CassandraDomainList cassandraDomainList) {
+        return InitilizationOperationBuilder
+            .forClass(CassandraDomainList.class)
+            .init(() -> cassandraDomainList.configure(configuration));
     }
 }
diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraRecipientRewriteTableModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraRecipientRewriteTableModule.java
index c20887e..939f641 100644
--- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraRecipientRewriteTableModule.java
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraRecipientRewriteTableModule.java
@@ -19,7 +19,6 @@
 package org.apache.james.modules.data;
 
 import org.apache.james.backends.cassandra.components.CassandraModule;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.rrt.api.RecipientRewriteTable;
 import org.apache.james.rrt.cassandra.CassandraMappingsSourcesDAO;
 import org.apache.james.rrt.cassandra.CassandraRRTModule;
@@ -27,15 +26,14 @@ import org.apache.james.rrt.cassandra.CassandraRecipientRewriteTable;
 import org.apache.james.rrt.cassandra.CassandraRecipientRewriteTableDAO;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Scopes;
-import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class CassandraRecipientRewriteTableModule extends AbstractModule {
-
     @Override
     public void configure() {
         bind(CassandraRecipientRewriteTable.class).in(Scopes.SINGLETON);
@@ -44,29 +42,12 @@ public class CassandraRecipientRewriteTableModule extends AbstractModule {
         bind(RecipientRewriteTable.class).to(CassandraRecipientRewriteTable.class);
         Multibinder<CassandraModule> cassandraDataDefinitions = Multibinder.newSetBinder(binder(), CassandraModule.class);
         cassandraDataDefinitions.addBinding().toInstance(CassandraRRTModule.MODULE);
-        Multibinder.newSetBinder(binder(), InitializationOperation.class).addBinding().to(CassandraRecipientRewriteTablePerformer.class);
     }
 
-    @Singleton
-    public static class CassandraRecipientRewriteTablePerformer implements InitializationOperation {
-        private final ConfigurationProvider configurationProvider;
-        private final CassandraRecipientRewriteTable recipientRewriteTable;
-
-        @Inject
-        public CassandraRecipientRewriteTablePerformer(ConfigurationProvider configurationProvider, CassandraRecipientRewriteTable recipientRewriteTable) {
-            this.configurationProvider = configurationProvider;
-            this.recipientRewriteTable = recipientRewriteTable;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            recipientRewriteTable.configure(configurationProvider.getConfiguration("recipientrewritetable"));
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return CassandraRecipientRewriteTable.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation configureRecipientRewriteTable(ConfigurationProvider configurationProvider, CassandraRecipientRewriteTable recipientRewriteTable) {
+        return InitilizationOperationBuilder
+            .forClass(CassandraRecipientRewriteTable.class)
+            .init(() -> recipientRewriteTable.configure(configurationProvider.getConfiguration("recipientrewritetable")));
     }
-
 }
diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraUsersRepositoryModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraUsersRepositoryModule.java
index 457af24..5f38aa5 100644
--- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraUsersRepositoryModule.java
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraUsersRepositoryModule.java
@@ -19,17 +19,16 @@
 package org.apache.james.modules.data;
 
 import org.apache.james.backends.cassandra.components.CassandraModule;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.cassandra.CassandraUsersRepository;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Scopes;
-import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class CassandraUsersRepositoryModule extends AbstractModule {
     @Override
@@ -38,31 +37,12 @@ public class CassandraUsersRepositoryModule extends AbstractModule {
         bind(UsersRepository.class).to(CassandraUsersRepository.class);
         Multibinder<CassandraModule> cassandraDataDefinitions = Multibinder.newSetBinder(binder(), CassandraModule.class);
         cassandraDataDefinitions.addBinding().toInstance(org.apache.james.user.cassandra.CassandraUsersRepositoryModule.MODULE);
-
-        Multibinder.newSetBinder(binder(), InitializationOperation.class).addBinding().to(CassandraUsersRepositoryInitializationOperation.class);
     }
 
-    @Singleton
-    public static class CassandraUsersRepositoryInitializationOperation implements InitializationOperation {
-
-        private final ConfigurationProvider configurationProvider;
-        private final CassandraUsersRepository usersRepository;
-
-        @Inject
-        public CassandraUsersRepositoryInitializationOperation(ConfigurationProvider configurationProvider, CassandraUsersRepository usersRepository) {
-            this.configurationProvider = configurationProvider;
-            this.usersRepository = usersRepository;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            usersRepository.configure(configurationProvider.getConfiguration("usersrepository"));
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return CassandraUsersRepository.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation configureUsersRepository(ConfigurationProvider configurationProvider, CassandraUsersRepository usersRepository) {
+        return InitilizationOperationBuilder
+            .forClass(CassandraUsersRepository.class)
+            .init(() -> usersRepository.configure(configurationProvider.getConfiguration("usersrepository")));
     }
-
 }
diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchMailboxModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchMailboxModule.java
index f7e12f2..6bd4f54 100644
--- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchMailboxModule.java
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchMailboxModule.java
@@ -47,6 +47,7 @@ import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.store.search.ListeningMessageSearchIndex;
 import org.apache.james.mailbox.store.search.MessageSearchIndex;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 import org.apache.james.utils.PropertiesProvider;
 import org.elasticsearch.client.RestHighLevelClient;
 import org.slf4j.Logger;
@@ -56,6 +57,7 @@ import com.google.inject.AbstractModule;
 import com.google.inject.Provides;
 import com.google.inject.Scopes;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class ElasticSearchMailboxModule extends AbstractModule {
 
@@ -83,25 +85,6 @@ public class ElasticSearchMailboxModule extends AbstractModule {
         }
     }
 
-    static class ElasticSearchMailboxIndexCreationPerformer implements InitializationOperation {
-        private final MailboxIndexCreator mailboxIndexCreator;
-
-        @Inject
-        ElasticSearchMailboxIndexCreationPerformer(MailboxIndexCreator mailboxIndexCreator) {
-            this.mailboxIndexCreator = mailboxIndexCreator;
-        }
-
-        @Override
-        public void initModule()  throws Exception {
-            mailboxIndexCreator.createIndex();
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return MailboxIndexCreator.class;
-        }
-    }
-
     private static final Logger LOGGER = LoggerFactory.getLogger(ElasticSearchMailboxModule.class);
 
     public static final String ELASTICSEARCH_CONFIGURATION_NAME = "elasticsearch";
@@ -118,10 +101,6 @@ public class ElasticSearchMailboxModule extends AbstractModule {
             .addBinding()
             .to(ElasticSearchListeningMessageSearchIndex.class);
 
-        Multibinder.newSetBinder(binder(), InitializationOperation.class)
-            .addBinding()
-            .to(ElasticSearchMailboxIndexCreationPerformer.class);
-
         Multibinder.newSetBinder(binder(), StartUpCheck.class)
             .addBinding()
             .to(ElasticSearchStartUpCheck.class);
@@ -184,4 +163,11 @@ public class ElasticSearchMailboxModule extends AbstractModule {
         return configuration.getIndexAttachment();
     }
 
+    @ProvidesIntoSet
+    InitializationOperation createIndex(MailboxIndexCreator instance) {
+        return InitilizationOperationBuilder
+            .forClass(MailboxIndexCreator.class)
+            .init(instance::createIndex);
+    }
+
 }
diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchQuotaSearcherModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchQuotaSearcherModule.java
index 93eb8f1..fc98f6e 100644
--- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchQuotaSearcherModule.java
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchQuotaSearcherModule.java
@@ -39,6 +39,7 @@ import org.apache.james.quota.search.elasticsearch.QuotaSearchIndexCreationUtil;
 import org.apache.james.quota.search.elasticsearch.events.ElasticSearchQuotaMailboxListener;
 import org.apache.james.quota.search.elasticsearch.json.QuotaRatioToElasticSearchJson;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 import org.apache.james.utils.PropertiesProvider;
 import org.elasticsearch.client.RestHighLevelClient;
 import org.slf4j.Logger;
@@ -48,6 +49,7 @@ import com.google.inject.AbstractModule;
 import com.google.inject.Provides;
 import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class ElasticSearchQuotaSearcherModule extends AbstractModule {
 
@@ -74,25 +76,6 @@ public class ElasticSearchQuotaSearcherModule extends AbstractModule {
         }
     }
 
-    static class ElasticSearchQuotaIndexCreationPerformer implements InitializationOperation {
-        private final ElasticSearchQuotaIndexCreator indexCreator;
-
-        @Inject
-        ElasticSearchQuotaIndexCreationPerformer(ElasticSearchQuotaIndexCreator indexCreator) {
-            this.indexCreator = indexCreator;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            indexCreator.createIndex();
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return ElasticSearchQuotaIndexCreator.class;
-        }
-    }
-
     private static final Logger LOGGER = LoggerFactory.getLogger(ElasticSearchQuotaSearcherModule.class);
 
     @Override
@@ -100,10 +83,6 @@ public class ElasticSearchQuotaSearcherModule extends AbstractModule {
         Multibinder.newSetBinder(binder(), MailboxListener.GroupMailboxListener.class)
             .addBinding()
             .to(ElasticSearchQuotaMailboxListener.class);
-
-        Multibinder.newSetBinder(binder(), InitializationOperation.class)
-            .addBinding()
-            .to(ElasticSearchQuotaIndexCreationPerformer.class);
     }
 
     @Provides
@@ -134,4 +113,11 @@ public class ElasticSearchQuotaSearcherModule extends AbstractModule {
                 configuration.getWriteAliasQuotaRatioName()),
                 new QuotaRatioToElasticSearchJson());
     }
+
+    @ProvidesIntoSet
+    InitializationOperation createIndex(ElasticSearchQuotaIndexCreator instance) {
+        return InitilizationOperationBuilder
+            .forClass(ElasticSearchQuotaIndexCreator.class)
+            .init(instance::createIndex);
+    }
 }
diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/metrics/CassandraMetricsModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/metrics/CassandraMetricsModule.java
index 9491b24..f8a3520 100644
--- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/metrics/CassandraMetricsModule.java
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/metrics/CassandraMetricsModule.java
@@ -21,48 +21,32 @@ package org.apache.james.modules.metrics;
 
 import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.codahale.metrics.MetricRegistry;
 import com.datastax.driver.core.Session;
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Scopes;
-import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class CassandraMetricsModule extends AbstractModule {
-
     @Override
     protected void configure() {
         bind(CassandraMetricsInjector.class)
             .in(Scopes.SINGLETON);
-
-        Multibinder.newSetBinder(binder(), InitializationOperation.class)
-            .addBinding()
-            .to(CassandraMetricsInjector.class);
     }
 
-    public static class CassandraMetricsInjector implements InitializationOperation, Startable {
-
-        private final MetricRegistry metricRegistry;
-        private final Session session;
-
-        @Inject
-        public CassandraMetricsInjector(MetricRegistry metricRegistry, Session session) {
-            this.metricRegistry = metricRegistry;
-            this.session = session;
-        }
-
-        @Override
-        public void initModule() {
-            metricRegistry.registerAll(
+    @ProvidesIntoSet
+    InitializationOperation injectMetrics(MetricRegistry metricRegistry, Session session) {
+        return InitilizationOperationBuilder
+            .forClass(CassandraMetricsInjector.class)
+            .init(() -> metricRegistry.registerAll(
                 session.getCluster()
                     .getMetrics()
-                    .getRegistry());
-        }
+                    .getRegistry()));
+    }
+
+    public static class CassandraMetricsInjector implements Startable {
 
-        @Override
-        public Class<? extends Startable> forClass() {
-            return CassandraMetricsInjector.class;
-        }
     }
 }
diff --git a/server/container/guice/cassandra-ldap-guice/src/main/java/org/apache/james/data/LdapUsersRepositoryModule.java b/server/container/guice/cassandra-ldap-guice/src/main/java/org/apache/james/data/LdapUsersRepositoryModule.java
index 0b058ae..bdee231 100644
--- a/server/container/guice/cassandra-ldap-guice/src/main/java/org/apache/james/data/LdapUsersRepositoryModule.java
+++ b/server/container/guice/cassandra-ldap-guice/src/main/java/org/apache/james/data/LdapUsersRepositoryModule.java
@@ -19,28 +19,24 @@
 package org.apache.james.data;
 
 import org.apache.commons.configuration2.ex.ConfigurationException;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.ldap.LdapRepositoryConfiguration;
 import org.apache.james.user.ldap.ReadOnlyUsersLDAPRepository;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Provides;
 import com.google.inject.Scopes;
 import com.google.inject.Singleton;
-import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class LdapUsersRepositoryModule extends AbstractModule {
-
     @Override
     public void configure() {
         bind(ReadOnlyUsersLDAPRepository.class).in(Scopes.SINGLETON);
         bind(UsersRepository.class).to(ReadOnlyUsersLDAPRepository.class);
-
-        Multibinder.newSetBinder(binder(), InitializationOperation.class).addBinding().to(LdapUsersRepositoryInitializationOperation.class);
     }
 
     @Provides
@@ -50,26 +46,13 @@ public class LdapUsersRepositoryModule extends AbstractModule {
             configurationProvider.getConfiguration("usersrepository"));
     }
 
-    @Singleton
-    public static class LdapUsersRepositoryInitializationOperation implements InitializationOperation {
-        private final LdapRepositoryConfiguration configuration;
-        private final ReadOnlyUsersLDAPRepository usersRepository;
-
-        @Inject
-        public LdapUsersRepositoryInitializationOperation(LdapRepositoryConfiguration configuration, ReadOnlyUsersLDAPRepository usersRepository) {
-            this.configuration = configuration;
-            this.usersRepository = usersRepository;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            usersRepository.configure(configuration);
-            usersRepository.init();
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return ReadOnlyUsersLDAPRepository.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation configureLdap(LdapRepositoryConfiguration configuration, ReadOnlyUsersLDAPRepository usersRepository) {
+        return InitilizationOperationBuilder
+            .forClass(ReadOnlyUsersLDAPRepository.class)
+            .init(() -> {
+                usersRepository.configure(configuration);
+                usersRepository.init();
+            });
     }
 }
diff --git a/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/event/RabbitMQEventBusModule.java b/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/event/RabbitMQEventBusModule.java
index 41e8fc9..038afb6 100644
--- a/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/event/RabbitMQEventBusModule.java
+++ b/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/event/RabbitMQEventBusModule.java
@@ -20,18 +20,18 @@
 package org.apache.james.modules.event;
 
 import org.apache.james.event.json.EventSerializer;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.events.MailboxIdRegistrationKey;
 import org.apache.james.mailbox.events.RabbitMQEventBus;
 import org.apache.james.mailbox.events.RegistrationKey;
 import org.apache.james.mailbox.events.RetryBackoffConfiguration;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Scopes;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class RabbitMQEventBusModule extends AbstractModule {
 
@@ -45,28 +45,13 @@ public class RabbitMQEventBusModule extends AbstractModule {
         Multibinder.newSetBinder(binder(), RegistrationKey.Factory.class)
             .addBinding().to(MailboxIdRegistrationKey.Factory.class);
 
-        Multibinder.newSetBinder(binder(), InitializationOperation.class)
-            .addBinding().to(RabbitMQEventBusInitializer.class);
-
         bind(RetryBackoffConfiguration.class).toInstance(RetryBackoffConfiguration.DEFAULT);
     }
 
-    static class RabbitMQEventBusInitializer implements InitializationOperation {
-        private final RabbitMQEventBus rabbitMQEventBus;
-
-        @Inject
-        RabbitMQEventBusInitializer(RabbitMQEventBus rabbitMQEventBus) {
-            this.rabbitMQEventBus = rabbitMQEventBus;
-        }
-
-        @Override
-        public void initModule() {
-            rabbitMQEventBus.start();
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return RabbitMQEventBus.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation workQueue(RabbitMQEventBus instance) {
+        return InitilizationOperationBuilder
+            .forClass(RabbitMQEventBus.class)
+            .init(instance::start);
     }
 }
diff --git a/server/container/guice/es-metric-reporter/src/main/java/org/apache/james/modules/server/ElasticSearchMetricReporterModule.java b/server/container/guice/es-metric-reporter/src/main/java/org/apache/james/modules/server/ElasticSearchMetricReporterModule.java
index d0bf64b..f38f0ef 100644
--- a/server/container/guice/es-metric-reporter/src/main/java/org/apache/james/modules/server/ElasticSearchMetricReporterModule.java
+++ b/server/container/guice/es-metric-reporter/src/main/java/org/apache/james/modules/server/ElasticSearchMetricReporterModule.java
@@ -23,19 +23,18 @@ import java.io.FileNotFoundException;
 
 import org.apache.commons.configuration2.Configuration;
 import org.apache.commons.configuration2.ex.ConfigurationException;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.metrics.es.ESMetricReporter;
 import org.apache.james.metrics.es.ESReporterConfiguration;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 import org.apache.james.utils.PropertiesProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Provides;
 import com.google.inject.Singleton;
-import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class ElasticSearchMetricReporterModule extends AbstractModule {
     private static final String ELASTICSEARCH_CONFIGURATION_NAME = "elasticsearch";
@@ -46,11 +45,6 @@ public class ElasticSearchMetricReporterModule extends AbstractModule {
     public static final boolean DEFAULT_DISABLE = false;
     public static final int DEFAULT_ES_HTTP_PORT = 9200;
 
-    @Override
-    protected void configure() {
-        Multibinder.newSetBinder(binder(), InitializationOperation.class).addBinding().to(ESMetricReporterStarter.class);
-    }
-
     @Provides
     @Singleton
     public ESReporterConfiguration provideConfiguration(PropertiesProvider propertiesProvider) throws ConfigurationException {
@@ -83,24 +77,10 @@ public class ElasticSearchMetricReporterModule extends AbstractModule {
         return propertiesReader.getBoolean("elasticsearch.metrics.reports.enabled", DEFAULT_DISABLE);
     }
 
-    @Singleton
-    public static class ESMetricReporterStarter implements InitializationOperation {
-        private final ESMetricReporter esMetricReporter;
-
-        @Inject
-        public ESMetricReporterStarter(ESMetricReporter esMetricReporter) {
-            this.esMetricReporter = esMetricReporter;
-        }
-
-        @Override
-        public void initModule() {
-            esMetricReporter.start();
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return ESMetricReporter.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation startReporter(ESMetricReporter instance) {
+        return InitilizationOperationBuilder
+            .forClass(ESMetricReporter.class)
+            .init(instance::start);
     }
-
 }
diff --git a/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/DNSServiceModule.java b/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/DNSServiceModule.java
index 3736d6a..60bb81e 100644
--- a/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/DNSServiceModule.java
+++ b/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/DNSServiceModule.java
@@ -20,46 +20,28 @@ package org.apache.james.modules.server;
 
 import org.apache.james.dnsservice.api.DNSService;
 import org.apache.james.dnsservice.dnsjava.DNSJavaService;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Scopes;
-import com.google.inject.Singleton;
-import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class DNSServiceModule extends AbstractModule {
-
     @Override
     protected void configure() {
         bind(DNSJavaService.class).in(Scopes.SINGLETON);
         bind(DNSService.class).to(DNSJavaService.class);
-        Multibinder.newSetBinder(binder(), InitializationOperation.class).addBinding().to(DNSServiceInitializationOperation.class);
     }
 
-    @Singleton
-    public static class DNSServiceInitializationOperation implements InitializationOperation {
-        private final ConfigurationProvider configurationProvider;
-        private final DNSJavaService dnsService;
-
-        @Inject
-        public DNSServiceInitializationOperation(ConfigurationProvider configurationProvider,
-                                                 DNSJavaService dnsService) {
-            this.configurationProvider = configurationProvider;
-            this.dnsService = dnsService;
-        }
-
-        @Override
-        public void initModule()  throws Exception {
-            dnsService.configure(configurationProvider.getConfiguration("dnsservice"));
-            dnsService.init();
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return DNSJavaService.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation configureDNS(ConfigurationProvider configurationProvider, DNSJavaService dnsService) {
+        return InitilizationOperationBuilder
+            .forClass(DNSJavaService.class)
+            .init(() -> {
+                dnsService.configure(configurationProvider.getConfiguration("dnsservice"));
+                dnsService.init();
+            });
     }
 }
\ No newline at end of file
diff --git a/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/DropWizardMetricsModule.java b/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/DropWizardMetricsModule.java
index 8893fbe..fa542ea 100644
--- a/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/DropWizardMetricsModule.java
+++ b/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/DropWizardMetricsModule.java
@@ -19,20 +19,18 @@
 
 package org.apache.james.modules.server;
 
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.metrics.api.GaugeRegistry;
 import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.metrics.dropwizard.DropWizardGaugeRegistry;
 import org.apache.james.metrics.dropwizard.DropWizardJVMMetrics;
 import org.apache.james.metrics.dropwizard.DropWizardMetricFactory;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.codahale.metrics.MetricRegistry;
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Scopes;
-import com.google.inject.Singleton;
-import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class DropWizardMetricsModule extends AbstractModule {
 
@@ -45,30 +43,19 @@ public class DropWizardMetricsModule extends AbstractModule {
         bind(MetricFactory.class).to(DropWizardMetricFactory.class);
 
         bind(GaugeRegistry.class).to(DropWizardGaugeRegistry.class);
-
-        Multibinder.newSetBinder(binder(), InitializationOperation.class).addBinding().to(DropWizardInitializationOperation.class);
     }
 
-    @Singleton
-    public static class DropWizardInitializationOperation implements InitializationOperation, Startable {
-        private final DropWizardMetricFactory dropWizardMetricFactory;
-        private final DropWizardJVMMetrics dropWizardJVMMetrics;
-
-        @Inject
-        public DropWizardInitializationOperation(DropWizardMetricFactory dropWizardMetricFactory, DropWizardJVMMetrics dropWizardJVMMetrics) {
-            this.dropWizardMetricFactory = dropWizardMetricFactory;
-            this.dropWizardJVMMetrics = dropWizardJVMMetrics;
-        }
-
-        @Override
-        public void initModule() {
-            dropWizardMetricFactory.start();
-            dropWizardJVMMetrics.start();
-        }
+    @ProvidesIntoSet
+    InitializationOperation startMetricFactory(DropWizardMetricFactory instance) {
+        return InitilizationOperationBuilder
+            .forClass(DropWizardMetricFactory.class)
+            .init(instance::start);
+    }
 
-        @Override
-        public Class<? extends Startable> forClass() {
-            return DropWizardInitializationOperation.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation startJVMMetrics(DropWizardJVMMetrics instance) {
+        return InitilizationOperationBuilder
+            .forClass(DropWizardJVMMetrics.class)
+            .init(instance::start);
     }
 }
diff --git a/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/MailStoreRepositoryModule.java b/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/MailStoreRepositoryModule.java
index 6822d80..bf6eee1 100644
--- a/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/MailStoreRepositoryModule.java
+++ b/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/MailStoreRepositoryModule.java
@@ -24,7 +24,6 @@ import java.util.function.Supplier;
 import org.apache.commons.configuration2.HierarchicalConfiguration;
 import org.apache.commons.configuration2.ex.ConfigurationException;
 import org.apache.commons.configuration2.tree.ImmutableNode;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.mailrepository.api.MailRepositoryStore;
 import org.apache.james.mailrepository.memory.MailRepositoryLoader;
 import org.apache.james.mailrepository.memory.MailRepositoryStoreConfiguration;
@@ -32,19 +31,19 @@ import org.apache.james.mailrepository.memory.MemoryMailRepositoryStore;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.utils.GuiceProbe;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 import org.apache.james.utils.MailRepositoryProbeImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Provides;
 import com.google.inject.Scopes;
 import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class MailStoreRepositoryModule extends AbstractModule {
-
     public static final Logger LOGGER = LoggerFactory.getLogger(MailStoreRepositoryModule.class);
 
     public interface DefaultItemSupplier extends Supplier<MailRepositoryStoreConfiguration.Item> {}
@@ -57,7 +56,6 @@ public class MailStoreRepositoryModule extends AbstractModule {
         bind(GuiceMailRepositoryLoader.class).in(Scopes.SINGLETON);
         bind(MailRepositoryLoader.class).to(GuiceMailRepositoryLoader.class);
 
-        Multibinder.newSetBinder(binder(), InitializationOperation.class).addBinding().to(MailRepositoryStoreModuleInitializationOperation.class);
         Multibinder.newSetBinder(binder(), GuiceProbe.class).addBinding().to(MailRepositoryProbeImpl.class);
     }
 
@@ -73,24 +71,10 @@ public class MailStoreRepositoryModule extends AbstractModule {
         return MailRepositoryStoreConfiguration.forItems(defaultItemSupplier.get());
     }
 
-    @Singleton
-    public static class MailRepositoryStoreModuleInitializationOperation implements InitializationOperation {
-        private final MemoryMailRepositoryStore javaMailRepositoryStore;
-
-        @Inject
-        public MailRepositoryStoreModuleInitializationOperation(MemoryMailRepositoryStore javaMailRepositoryStore) {
-            this.javaMailRepositoryStore = javaMailRepositoryStore;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            javaMailRepositoryStore.init();
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return MemoryMailRepositoryStore.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation startMailStore(MemoryMailRepositoryStore instance) {
+        return InitilizationOperationBuilder
+            .forClass(MemoryMailRepositoryStore.class)
+            .init(instance::init);
     }
-
 }
diff --git a/server/container/guice/jmx/src/main/java/org/apache/james/modules/server/JMXServerModule.java b/server/container/guice/jmx/src/main/java/org/apache/james/modules/server/JMXServerModule.java
index 0f0fdbe..36e6579 100644
--- a/server/container/guice/jmx/src/main/java/org/apache/james/modules/server/JMXServerModule.java
+++ b/server/container/guice/jmx/src/main/java/org/apache/james/modules/server/JMXServerModule.java
@@ -33,7 +33,6 @@ import org.apache.james.adapter.mailbox.ReIndexerManagement;
 import org.apache.james.adapter.mailbox.ReIndexerManagementMBean;
 import org.apache.james.domainlist.api.DomainListManagementMBean;
 import org.apache.james.domainlist.lib.DomainListManagement;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.mailbox.copier.MailboxCopier;
 import org.apache.james.mailbox.indexer.ReIndexer;
 import org.apache.james.mailbox.tools.copier.MailboxCopierImpl;
@@ -47,17 +46,17 @@ import org.apache.james.user.api.UsersRepositoryManagementMBean;
 import org.apache.james.user.lib.UsersRepositoryManagement;
 import org.apache.james.utils.GuiceMailboxManagerResolver;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 import org.apache.james.utils.PropertiesProvider;
 import org.apache.mailbox.tools.indexer.ReIndexerImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Provides;
 import com.google.inject.Scopes;
 import com.google.inject.Singleton;
-import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 import com.google.inject.name.Names;
 
 public class JMXServerModule extends AbstractModule {
@@ -96,8 +95,6 @@ public class JMXServerModule extends AbstractModule {
         bind(ReIndexerManagementMBean.class).to(ReIndexerManagement.class);
         bind(QuotaManagementMBean.class).to(QuotaManagement.class);
         bind(SieveRepositoryManagementMBean.class).to(SieveRepositoryManagement.class);
-        Multibinder<InitializationOperation> configurationMultibinder = Multibinder.newSetBinder(binder(), InitializationOperation.class);
-        configurationMultibinder.addBinding().to(JMXModuleInitializationOperation.class);
     }
 
     @Provides
@@ -111,57 +108,28 @@ public class JMXServerModule extends AbstractModule {
         }
     }
 
-    @Singleton
-    public static class JMXModuleInitializationOperation implements InitializationOperation {
-
-        private final JMXServer jmxServer;
-        private final DomainListManagementMBean domainListManagementMBean;
-        private final UsersRepositoryManagementMBean usersRepositoryManagementMBean;
-        private final RecipientRewriteTableManagementMBean recipientRewriteTableManagementMBean;
-        private final MailboxManagerManagementMBean mailboxManagerManagementMBean;
-        private final MailboxCopierManagementMBean mailboxCopierManagementMBean;
-        private final ReIndexerManagementMBean reIndexerManagementMBean;
-        private final QuotaManagementMBean quotaManagementMBean;
-        private final SieveRepositoryManagementMBean sieveRepositoryManagementMBean;
-
-        @Inject
-        public JMXModuleInitializationOperation(JMXServer jmxServer,
-                                                DomainListManagementMBean domainListManagementMBean,
-                                                UsersRepositoryManagementMBean usersRepositoryManagementMBean,
-                                                RecipientRewriteTableManagementMBean recipientRewriteTableManagementMBean,
-                                                MailboxManagerManagementMBean mailboxManagerManagementMBean,
-                                                MailboxCopierManagementMBean mailboxCopierManagementMBean,
-                                                ReIndexerManagementMBean reIndexerManagementMBean,
-                                                QuotaManagementMBean quotaManagementMBean,
-                                                SieveRepositoryManagementMBean sieveRepositoryManagementMBean) {
-            this.jmxServer = jmxServer;
-            this.domainListManagementMBean = domainListManagementMBean;
-            this.usersRepositoryManagementMBean = usersRepositoryManagementMBean;
-            this.recipientRewriteTableManagementMBean = recipientRewriteTableManagementMBean;
-            this.mailboxManagerManagementMBean = mailboxManagerManagementMBean;
-            this.mailboxCopierManagementMBean = mailboxCopierManagementMBean;
-            this.reIndexerManagementMBean = reIndexerManagementMBean;
-            this.quotaManagementMBean = quotaManagementMBean;
-            this.sieveRepositoryManagementMBean = sieveRepositoryManagementMBean;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            jmxServer.start();
-            jmxServer.register(JMX_COMPONENT_DOMAINLIST, domainListManagementMBean);
-            jmxServer.register(JMX_COMPONENT_USERS_REPOSITORY, usersRepositoryManagementMBean);
-            jmxServer.register(JMX_COMPONENT_RECIPIENTREWRITETABLE, recipientRewriteTableManagementMBean);
-            jmxServer.register(JMX_COMPONENT_NAME_MAILBOXMANAGERBEAN, mailboxManagerManagementMBean);
-            jmxServer.register(JMX_COMPONENT_MAILBOXCOPIER, mailboxCopierManagementMBean);
-            jmxServer.register(JMX_COMPONENT_REINDEXER, reIndexerManagementMBean);
-            jmxServer.register(JMX_COMPONENT_QUOTA, quotaManagementMBean);
-            jmxServer.register(JMX_COMPONENT_SIEVE, sieveRepositoryManagementMBean);
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return JMXServer.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation startJmxServer(JMXServer jmxServer,
+                                        DomainListManagementMBean domainListManagementMBean,
+                                        UsersRepositoryManagementMBean usersRepositoryManagementMBean,
+                                        RecipientRewriteTableManagementMBean recipientRewriteTableManagementMBean,
+                                        MailboxManagerManagementMBean mailboxManagerManagementMBean,
+                                        MailboxCopierManagementMBean mailboxCopierManagementMBean,
+                                        ReIndexerManagementMBean reIndexerManagementMBean,
+                                        QuotaManagementMBean quotaManagementMBean,
+                                        SieveRepositoryManagementMBean sieveRepositoryManagementMBean) {
+        return InitilizationOperationBuilder
+            .forClass(JMXServer.class)
+            .init(() -> {
+                jmxServer.start();
+                jmxServer.register(JMX_COMPONENT_DOMAINLIST, domainListManagementMBean);
+                jmxServer.register(JMX_COMPONENT_USERS_REPOSITORY, usersRepositoryManagementMBean);
+                jmxServer.register(JMX_COMPONENT_RECIPIENTREWRITETABLE, recipientRewriteTableManagementMBean);
+                jmxServer.register(JMX_COMPONENT_NAME_MAILBOXMANAGERBEAN, mailboxManagerManagementMBean);
+                jmxServer.register(JMX_COMPONENT_MAILBOXCOPIER, mailboxCopierManagementMBean);
+                jmxServer.register(JMX_COMPONENT_REINDEXER, reIndexerManagementMBean);
+                jmxServer.register(JMX_COMPONENT_QUOTA, quotaManagementMBean);
+                jmxServer.register(JMX_COMPONENT_SIEVE, sieveRepositoryManagementMBean);
+            });
     }
-
 }
diff --git a/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPADomainListModule.java b/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPADomainListModule.java
index a1a5bca..b675f70 100644
--- a/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPADomainListModule.java
+++ b/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPADomainListModule.java
@@ -22,24 +22,21 @@ import org.apache.commons.configuration2.ex.ConfigurationException;
 import org.apache.james.domainlist.api.DomainList;
 import org.apache.james.domainlist.jpa.JPADomainList;
 import org.apache.james.domainlist.lib.DomainListConfiguration;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Provides;
 import com.google.inject.Scopes;
 import com.google.inject.Singleton;
-import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class JPADomainListModule extends AbstractModule {
-
     @Override
     public void configure() {
         bind(JPADomainList.class).in(Scopes.SINGLETON);
         bind(DomainList.class).to(JPADomainList.class);
-        Multibinder.newSetBinder(binder(), InitializationOperation.class).addBinding().to(JPADomainListInitializationOperation.class);
     }
 
     @Provides
@@ -51,26 +48,11 @@ public class JPADomainListModule extends AbstractModule {
             throw new RuntimeException(e);
         }
     }
-    
-    @Singleton
-    public static class JPADomainListInitializationOperation implements InitializationOperation {
-        private final DomainListConfiguration configuration;
-        private final JPADomainList jpaDomainList;
-
-        @Inject
-        public JPADomainListInitializationOperation(DomainListConfiguration configuration, JPADomainList jpaDomainList) {
-            this.configuration = configuration;
-            this.jpaDomainList = jpaDomainList;
-        }
 
-        @Override
-        public void initModule() throws Exception {
-            jpaDomainList.configure(configuration);
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return JPADomainList.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation configureDomainList(DomainListConfiguration configuration, JPADomainList jpaDomainList) {
+        return InitilizationOperationBuilder
+            .forClass(JPADomainList.class)
+            .init(() -> jpaDomainList.configure(configuration));
     }
 }
diff --git a/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPARecipientRewriteTableModule.java b/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPARecipientRewriteTableModule.java
index c57f1ff..b0456f1 100644
--- a/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPARecipientRewriteTableModule.java
+++ b/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPARecipientRewriteTableModule.java
@@ -18,47 +18,27 @@
  ****************************************************************/
 package org.apache.james.modules.data;
 
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.rrt.api.RecipientRewriteTable;
 import org.apache.james.rrt.jpa.JPARecipientRewriteTable;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Scopes;
-import com.google.inject.Singleton;
-import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class JPARecipientRewriteTableModule extends AbstractModule {
-
     @Override
     public void configure() {
         bind(JPARecipientRewriteTable.class).in(Scopes.SINGLETON);
         bind(RecipientRewriteTable.class).to(JPARecipientRewriteTable.class);
-        Multibinder.newSetBinder(binder(), InitializationOperation.class).addBinding().to(JPARecipientRewriteTablePerformer.class);
     }
 
-    @Singleton
-    public static class JPARecipientRewriteTablePerformer implements InitializationOperation {
-        private final ConfigurationProvider configurationProvider;
-        private final JPARecipientRewriteTable recipientRewriteTable;
-
-        @Inject
-        public JPARecipientRewriteTablePerformer(ConfigurationProvider configurationProvider, JPARecipientRewriteTable recipientRewriteTable) {
-            this.configurationProvider = configurationProvider;
-            this.recipientRewriteTable = recipientRewriteTable;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            recipientRewriteTable.configure(configurationProvider.getConfiguration("recipientrewritetable"));
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return JPARecipientRewriteTable.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation configureRRT(ConfigurationProvider configurationProvider, JPARecipientRewriteTable recipientRewriteTable) {
+        return InitilizationOperationBuilder
+            .forClass(JPARecipientRewriteTable.class)
+            .init(() -> recipientRewriteTable.configure(configurationProvider.getConfiguration("recipientrewritetable")));
     }
-
 }
diff --git a/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPAUsersRepositoryModule.java b/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPAUsersRepositoryModule.java
index 5618705..5a71924 100644
--- a/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPAUsersRepositoryModule.java
+++ b/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPAUsersRepositoryModule.java
@@ -18,47 +18,27 @@
  ****************************************************************/
 package org.apache.james.modules.data;
 
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.jpa.JPAUsersRepository;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Scopes;
-import com.google.inject.Singleton;
-import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class JPAUsersRepositoryModule extends AbstractModule {
     @Override
     public void configure() {
         bind(JPAUsersRepository.class).in(Scopes.SINGLETON);
         bind(UsersRepository.class).to(JPAUsersRepository.class);
-
-        Multibinder.newSetBinder(binder(), InitializationOperation.class).addBinding().to(JPAUsersRepositoryInitializationOperation.class);
     }
 
-    @Singleton
-    public static class JPAUsersRepositoryInitializationOperation implements InitializationOperation {
-        private final ConfigurationProvider configurationProvider;
-        private final JPAUsersRepository usersRepository;
-
-        @Inject
-        public JPAUsersRepositoryInitializationOperation(ConfigurationProvider configurationProvider, JPAUsersRepository usersRepository) {
-            this.configurationProvider = configurationProvider;
-            this.usersRepository = usersRepository;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            usersRepository.configure(configurationProvider.getConfiguration("usersrepository"));
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return JPAUsersRepository.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation configureJpaUsers(ConfigurationProvider configurationProvider, JPAUsersRepository usersRepository) {
+        return InitilizationOperationBuilder
+            .forClass(JPAUsersRepository.class)
+            .init(() -> usersRepository.configure(configurationProvider.getConfiguration("usersrepository")));
     }
-
 }
diff --git a/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/DefaultEventModule.java b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/DefaultEventModule.java
index ea4b011..8e4d141 100644
--- a/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/DefaultEventModule.java
+++ b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/DefaultEventModule.java
@@ -19,10 +19,7 @@
 
 package org.apache.james.modules.mailbox;
 
-import javax.inject.Inject;
-
 import org.apache.commons.configuration2.ex.ConfigurationException;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.events.InVMEventBus;
 import org.apache.james.mailbox.events.MailboxListener;
@@ -33,18 +30,18 @@ import org.apache.james.modules.EventDeadLettersProbe;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.utils.GuiceProbe;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
 import com.google.inject.Provides;
 import com.google.inject.Scopes;
 import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class DefaultEventModule extends AbstractModule {
     @Override
     protected void configure() {
-        Multibinder.newSetBinder(binder(), InitializationOperation.class).addBinding().to(ListenerRegistrationPerformer.class);
-
         bind(MailboxListenerFactory.class).in(Scopes.SINGLETON);
         bind(MailboxListenersLoaderImpl.class).in(Scopes.SINGLETON);
         bind(InVmEventDelivery.class).in(Scopes.SINGLETON);
@@ -66,25 +63,10 @@ public class DefaultEventModule extends AbstractModule {
         return ListenersConfiguration.from(configurationProvider.getConfiguration("listeners"));
     }
 
-    @Singleton
-    public static class ListenerRegistrationPerformer implements InitializationOperation {
-        private final MailboxListenersLoaderImpl listeners;
-        private final ListenersConfiguration configuration;
-
-        @Inject
-        public ListenerRegistrationPerformer(MailboxListenersLoaderImpl listeners, ListenersConfiguration configuration) {
-            this.listeners = listeners;
-            this.configuration = configuration;
-        }
-
-        @Override
-        public void initModule() {
-            listeners.configure(configuration);
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return MailboxListenersLoaderImpl.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation registerListeners(MailboxListenersLoaderImpl listeners, ListenersConfiguration configuration) {
+        return InitilizationOperationBuilder
+            .forClass(MailboxListenersLoaderImpl.class)
+            .init(() -> listeners.configure(configuration));
     }
 }
diff --git a/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/CamelMailetContainerModule.java b/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/CamelMailetContainerModule.java
index 39fe4e2..3df1755 100644
--- a/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/CamelMailetContainerModule.java
+++ b/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/CamelMailetContainerModule.java
@@ -47,6 +47,7 @@ import org.apache.james.utils.GuiceMailetLoader;
 import org.apache.james.utils.GuiceMatcherLoader;
 import org.apache.james.utils.GuiceProbe;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 import org.apache.james.utils.MailetConfigurationOverride;
 import org.apache.james.utils.SpoolerProbe;
 import org.apache.mailet.Mailet;
@@ -62,6 +63,7 @@ import com.google.inject.Provides;
 import com.google.inject.Scopes;
 import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class CamelMailetContainerModule extends AbstractModule {
 
@@ -91,8 +93,6 @@ public class CamelMailetContainerModule extends AbstractModule {
         Multibinder.newSetBinder(binder(), GuiceProbe.class).addBinding().to(SpoolerProbe.class);
         Multibinder<InitializationOperation> initialisationOperations = Multibinder.newSetBinder(binder(), InitializationOperation.class);
         initialisationOperations.addBinding().to(MailetModuleInitializationOperation.class);
-        initialisationOperations.addBinding().to(SpoolerStarter.class);
-        initialisationOperations.addBinding().to(MailetContextInitializationOperation.class);
 
         Multibinder<CamelMailetContainerModule.TransportProcessorCheck> transportProcessorChecks = Multibinder.newSetBinder(binder(), CamelMailetContainerModule.TransportProcessorCheck.class);
         transportProcessorChecks.addBinding().toInstance(BCC_Check);
@@ -107,68 +107,40 @@ public class CamelMailetContainerModule extends AbstractModule {
         return camelContext;
     }
 
-    @Singleton
-    public static class SpoolerStarter implements InitializationOperation {
-        private final JamesMailSpooler jamesMailSpooler;
-        private final ConfigurationProvider configurationProvider;
-
-        @Inject
-        public SpoolerStarter(JamesMailSpooler jamesMailSpooler, ConfigurationProvider configurationProvider) {
-            this.jamesMailSpooler = jamesMailSpooler;
-            this.configurationProvider = configurationProvider;
-        }
-
-        @Override
-        public void initModule() {
-            jamesMailSpooler.configure(getJamesSpoolerConfiguration());
-            jamesMailSpooler.init();
-        }
-
-        private HierarchicalConfiguration<ImmutableNode> getJamesSpoolerConfiguration() {
-            try {
-                return configurationProvider.getConfiguration("mailetcontainer")
-                    .configurationAt("spooler");
-            } catch (Exception e) {
-                LOGGER.warn("Could not locate configuration for James Spooler. Assuming empty configuration for this component.");
-                return new BaseHierarchicalConfiguration();
-            }
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return JamesMailSpooler.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation startSpooler(JamesMailSpooler jamesMailSpooler, ConfigurationProvider configurationProvider) {
+        return InitilizationOperationBuilder
+            .forClass(JamesMailSpooler.class)
+            .init(() -> {
+                jamesMailSpooler.configure(getJamesSpoolerConfiguration(configurationProvider));
+                jamesMailSpooler.init();
+            });
     }
 
-    @Singleton
-    public static class MailetContextInitializationOperation implements InitializationOperation {
-        private final ConfigurationProvider configurationProvider;
-        private final JamesMailetContext mailetContext;
-
-        @Inject
-        public MailetContextInitializationOperation(ConfigurationProvider configurationProvider, JamesMailetContext mailetContext) {
-            this.configurationProvider = configurationProvider;
-            this.mailetContext = mailetContext;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            mailetContext.configure(getMailetContextConfiguration());
+    private HierarchicalConfiguration<ImmutableNode> getJamesSpoolerConfiguration(ConfigurationProvider configurationProvider) {
+        try {
+            return configurationProvider.getConfiguration("mailetcontainer")
+                .configurationAt("spooler");
+        } catch (Exception e) {
+            LOGGER.warn("Could not locate configuration for James Spooler. Assuming empty configuration for this component.");
+            return new BaseHierarchicalConfiguration();
         }
+    }
 
-        private HierarchicalConfiguration<ImmutableNode> getMailetContextConfiguration() {
-            try {
-                return configurationProvider.getConfiguration("mailetcontainer")
-                    .configurationAt("context");
-            } catch (Exception e) {
-                LOGGER.warn("Could not locate configuration for Mailet context. Assuming empty configuration for this component.");
-                return new BaseHierarchicalConfiguration();
-            }
-        }
+    @ProvidesIntoSet
+    InitializationOperation initMailetContext(ConfigurationProvider configurationProvider, JamesMailetContext mailetContext) {
+        return InitilizationOperationBuilder
+            .forClass(JamesMailetContext.class)
+            .init(() -> mailetContext.configure(getMailetContextConfiguration(configurationProvider)));
+    }
 
-        @Override
-        public Class<? extends Startable> forClass() {
-            return JamesMailetContext.class;
+    private HierarchicalConfiguration<ImmutableNode> getMailetContextConfiguration(ConfigurationProvider configurationProvider) {
+        try {
+            return configurationProvider.getConfiguration("mailetcontainer")
+                .configurationAt("context");
+        } catch (Exception e) {
+            LOGGER.warn("Could not locate configuration for Mailet context. Assuming empty configuration for this component.");
+            return new BaseHierarchicalConfiguration();
         }
     }
 
diff --git a/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java b/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java
index 0f867d8..5914a08 100644
--- a/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java
+++ b/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java
@@ -26,7 +26,6 @@ import org.apache.james.dlp.eventsourcing.EventSourcingDLPConfigurationStore;
 import org.apache.james.domainlist.api.DomainList;
 import org.apache.james.domainlist.lib.DomainListConfiguration;
 import org.apache.james.domainlist.memory.MemoryDomainList;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.mailrepository.api.MailRepositoryUrlStore;
 import org.apache.james.mailrepository.api.Protocol;
 import org.apache.james.mailrepository.memory.MailRepositoryStoreConfiguration;
@@ -39,14 +38,14 @@ import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.memory.MemoryUsersRepository;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.common.collect.ImmutableList;
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Provides;
 import com.google.inject.Scopes;
 import com.google.inject.Singleton;
-import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class MemoryDataModule extends AbstractModule {
     private static final MailRepositoryStoreConfiguration.Item MEMORY_MAILREPOSITORY_DEFAULT_DECLARATION = new MailRepositoryStoreConfiguration.Item(
@@ -76,10 +75,6 @@ public class MemoryDataModule extends AbstractModule {
         bind(EventSourcingDLPConfigurationStore.class).in(Scopes.SINGLETON);
         bind(DLPConfigurationStore.class).to(EventSourcingDLPConfigurationStore.class);
 
-        Multibinder<InitializationOperation> initialisationOperations = Multibinder.newSetBinder(binder(), InitializationOperation.class);
-        initialisationOperations.addBinding().to(MemoryRRTInitializationOperation.class);
-        initialisationOperations.addBinding().to(MemoryDomainListInitializationOperation.class);
-
         bind(MailStoreRepositoryModule.DefaultItemSupplier.class).toInstance(() -> MEMORY_MAILREPOSITORY_DEFAULT_DECLARATION);
     }
 
@@ -93,47 +88,17 @@ public class MemoryDataModule extends AbstractModule {
         }
     }
 
-    @Singleton
-    public static class MemoryDomainListInitializationOperation implements InitializationOperation {
-        private final DomainListConfiguration domainListConfiguration;
-        private final MemoryDomainList memoryDomainList;
-
-        @Inject
-        public MemoryDomainListInitializationOperation(DomainListConfiguration domainListConfiguration, MemoryDomainList memoryDomainList) {
-            this.domainListConfiguration = domainListConfiguration;
-            this.memoryDomainList = memoryDomainList;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            memoryDomainList.configure(domainListConfiguration);
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return MemoryDomainList.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation configureDomainList(DomainListConfiguration domainListConfiguration, MemoryDomainList memoryDomainList) {
+        return InitilizationOperationBuilder
+            .forClass(MemoryDomainList.class)
+            .init(() -> memoryDomainList.configure(domainListConfiguration));
     }
 
-    @Singleton
-    public static class MemoryRRTInitializationOperation implements InitializationOperation {
-        private final ConfigurationProvider configurationProvider;
-        private final MemoryRecipientRewriteTable memoryRecipientRewriteTable;
-
-        @Inject
-        public MemoryRRTInitializationOperation(ConfigurationProvider configurationProvider, MemoryRecipientRewriteTable memoryRecipientRewriteTable) {
-            this.configurationProvider = configurationProvider;
-            this.memoryRecipientRewriteTable = memoryRecipientRewriteTable;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            memoryRecipientRewriteTable.configure(configurationProvider.getConfiguration("recipientrewritetable"));
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return MemoryRecipientRewriteTable.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation configureRRT(ConfigurationProvider configurationProvider, MemoryRecipientRewriteTable memoryRecipientRewriteTable) {
+        return InitilizationOperationBuilder
+            .forClass(MemoryRecipientRewriteTable.class)
+            .init(() -> memoryRecipientRewriteTable.configure(configurationProvider.getConfiguration("recipientrewritetable")));
     }
 }
diff --git a/server/container/guice/protocols/imap/src/main/java/org/apache/james/modules/protocols/IMAPServerModule.java b/server/container/guice/protocols/imap/src/main/java/org/apache/james/modules/protocols/IMAPServerModule.java
index 53f1cfb..16d738b 100644
--- a/server/container/guice/protocols/imap/src/main/java/org/apache/james/modules/protocols/IMAPServerModule.java
+++ b/server/container/guice/protocols/imap/src/main/java/org/apache/james/modules/protocols/IMAPServerModule.java
@@ -26,7 +26,6 @@ import org.apache.james.imap.main.DefaultImapDecoderFactory;
 import org.apache.james.imap.processor.main.DefaultImapProcessorFactory;
 import org.apache.james.imapserver.netty.IMAPServerFactory;
 import org.apache.james.imapserver.netty.OioIMAPServerFactory;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.SubscriptionManager;
 import org.apache.james.mailbox.events.EventBus;
@@ -36,13 +35,14 @@ import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.utils.GuiceProbe;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Provides;
 import com.google.inject.Scopes;
 import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class IMAPServerModule extends AbstractModule {
 
@@ -51,7 +51,6 @@ public class IMAPServerModule extends AbstractModule {
         bind(IMAPServerFactory.class).in(Scopes.SINGLETON);
         bind(OioIMAPServerFactory.class).in(Scopes.SINGLETON);
 
-        Multibinder.newSetBinder(binder(), InitializationOperation.class).addBinding().to(IMAPModuleInitializationOperation.class);
         Multibinder.newSetBinder(binder(), GuiceProbe.class).addBinding().to(ImapGuiceProbe.class);
     }
 
@@ -85,27 +84,13 @@ public class IMAPServerModule extends AbstractModule {
         return new DefaultImapEncoderFactory().buildImapEncoder();
     }
 
-    @Singleton
-    public static class IMAPModuleInitializationOperation implements InitializationOperation {
-
-        private final ConfigurationProvider configurationProvider;
-        private final IMAPServerFactory imapServerFactory;
-
-        @Inject
-        public IMAPModuleInitializationOperation(ConfigurationProvider configurationProvider, IMAPServerFactory imapServerFactory) {
-            this.configurationProvider = configurationProvider;
-            this.imapServerFactory = imapServerFactory;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            imapServerFactory.configure(configurationProvider.getConfiguration("imapserver"));
-            imapServerFactory.init();
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return IMAPServerFactory.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation configureImap(ConfigurationProvider configurationProvider, IMAPServerFactory imapServerFactory) {
+        return InitilizationOperationBuilder
+            .forClass(IMAPServerFactory.class)
+            .init(() -> {
+                imapServerFactory.configure(configurationProvider.getConfiguration("imapserver"));
+                imapServerFactory.init();
+            });
     }
 }
\ No newline at end of file
diff --git a/server/container/guice/protocols/jmap-draft/src/main/java/org/apache/james/modules/protocols/JMAPDraftServerModule.java b/server/container/guice/protocols/jmap-draft/src/main/java/org/apache/james/modules/protocols/JMAPDraftServerModule.java
index bcfa7de..0cf3ebf 100644
--- a/server/container/guice/protocols/jmap-draft/src/main/java/org/apache/james/modules/protocols/JMAPDraftServerModule.java
+++ b/server/container/guice/protocols/jmap-draft/src/main/java/org/apache/james/modules/protocols/JMAPDraftServerModule.java
@@ -27,56 +27,39 @@ import org.apache.james.jmap.draft.JMAPServer;
 import org.apache.james.jmap.draft.JmapGuiceProbe;
 import org.apache.james.jmap.draft.MessageIdProbe;
 import org.apache.james.jmap.draft.crypto.JamesSignatureHandler;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.utils.GuiceProbe;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 import org.bouncycastle.jce.provider.BouncyCastleProvider;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class JMAPDraftServerModule extends AbstractModule {
 
     @Override
     protected void configure() {
         install(new JMAPModule());
-        Multibinder.newSetBinder(binder(), InitializationOperation.class).addBinding().to(JMAPModuleInitializationOperation.class);
         Multibinder.newSetBinder(binder(), GuiceProbe.class).addBinding().to(JmapGuiceProbe.class);
         Multibinder.newSetBinder(binder(), GuiceProbe.class).addBinding().to(MessageIdProbe.class);
     }
 
-    @Singleton
-    public static class JMAPModuleInitializationOperation implements InitializationOperation {
-        private final JMAPServer server;
-        private final JamesSignatureHandler signatureHandler;
-        private final JMAPConfiguration jmapConfiguration;
 
-        @Inject
-        public JMAPModuleInitializationOperation(JMAPServer server, JamesSignatureHandler signatureHandler, JMAPConfiguration jmapConfiguration) {
-            this.server = server;
-            this.signatureHandler = signatureHandler;
-            this.jmapConfiguration = jmapConfiguration;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            if (jmapConfiguration.isEnabled()) {
-                signatureHandler.init();
-                server.start();
-                registerPEMWithSecurityProvider();
-            }
-        }
-
-        private void registerPEMWithSecurityProvider() {
-            Security.addProvider(new BouncyCastleProvider());
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return JMAPServer.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation startJmap(JMAPServer server, JamesSignatureHandler signatureHandler, JMAPConfiguration jmapConfiguration) {
+        return InitilizationOperationBuilder
+            .forClass(JMAPServer.class)
+            .init(() -> {
+                if (jmapConfiguration.isEnabled()) {
+                    signatureHandler.init();
+                    server.start();
+                    registerPEMWithSecurityProvider();
+                }
+            });
     }
 
+    private void registerPEMWithSecurityProvider() {
+        Security.addProvider(new BouncyCastleProvider());
+    }
 }
diff --git a/server/container/guice/protocols/lmtp/src/main/java/org/apache/james/modules/protocols/LMTPServerModule.java b/server/container/guice/protocols/lmtp/src/main/java/org/apache/james/modules/protocols/LMTPServerModule.java
index 798dbf7..4d40003 100644
--- a/server/container/guice/protocols/lmtp/src/main/java/org/apache/james/modules/protocols/LMTPServerModule.java
+++ b/server/container/guice/protocols/lmtp/src/main/java/org/apache/james/modules/protocols/LMTPServerModule.java
@@ -19,53 +19,35 @@
 
 package org.apache.james.modules.protocols;
 
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.lmtpserver.netty.LMTPServerFactory;
 import org.apache.james.lmtpserver.netty.OioLMTPServerFactory;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.util.LoggingLevel;
 import org.apache.james.utils.GuiceProbe;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Scopes;
-import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class LMTPServerModule extends AbstractModule {
-
     @Override
     protected void configure() {
         bind(LMTPServerFactory.class).in(Scopes.SINGLETON);
         bind(OioLMTPServerFactory.class).in(Scopes.SINGLETON);
 
-        Multibinder.newSetBinder(binder(), InitializationOperation.class).addBinding().to(LMTPModuleInitializationOperation.class);
         Multibinder.newSetBinder(binder(), GuiceProbe.class).addBinding().to(LmtpGuiceProbe.class);
     }
 
-    @Singleton
-    public static class LMTPModuleInitializationOperation implements InitializationOperation {
-
-        private final ConfigurationProvider configurationProvider;
-        private final LMTPServerFactory lmtpServerFactory;
-
-        @Inject
-        public LMTPModuleInitializationOperation(ConfigurationProvider configurationProvider, LMTPServerFactory lmtpServerFactory) {
-            this.configurationProvider = configurationProvider;
-            this.lmtpServerFactory = lmtpServerFactory;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            lmtpServerFactory.configure(configurationProvider.getConfiguration("lmtpserver", LoggingLevel.INFO));
-            lmtpServerFactory.init();
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return LMTPServerFactory.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation configureLmtp(ConfigurationProvider configurationProvider, LMTPServerFactory lmtpServerFactory) {
+        return InitilizationOperationBuilder
+            .forClass(LMTPServerFactory.class)
+            .init(() -> {
+                lmtpServerFactory.configure(configurationProvider.getConfiguration("lmtpserver", LoggingLevel.INFO));
+                lmtpServerFactory.init();
+            });
     }
-
 }
diff --git a/server/container/guice/protocols/managedsieve/src/main/java/org/apache/james/modules/protocols/ManageSieveServerModule.java b/server/container/guice/protocols/managedsieve/src/main/java/org/apache/james/modules/protocols/ManageSieveServerModule.java
index a0be505..28b29cc 100644
--- a/server/container/guice/protocols/managedsieve/src/main/java/org/apache/james/modules/protocols/ManageSieveServerModule.java
+++ b/server/container/guice/protocols/managedsieve/src/main/java/org/apache/james/modules/protocols/ManageSieveServerModule.java
@@ -18,7 +18,6 @@
  ****************************************************************/
 package org.apache.james.modules.protocols;
 
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.managesieve.api.commands.CoreCommands;
 import org.apache.james.managesieve.core.CoreProcessor;
 import org.apache.james.managesieveserver.netty.ManageSieveServerFactory;
@@ -26,11 +25,11 @@ import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.util.LoggingLevel;
 import org.apache.james.utils.GuiceProbe;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class ManageSieveServerModule extends AbstractModule {
 
@@ -38,30 +37,16 @@ public class ManageSieveServerModule extends AbstractModule {
     protected void configure() {
         install(new SieveModule());
         bind(CoreCommands.class).to(CoreProcessor.class);
-        Multibinder.newSetBinder(binder(), InitializationOperation.class).addBinding().to(ManageSieveModuleInitializationOperation.class);
         Multibinder.newSetBinder(binder(), GuiceProbe.class).addBinding().to(SieveProbeImpl.class);
     }
 
-    @Singleton
-    public static class ManageSieveModuleInitializationOperation implements InitializationOperation {
-        private final ConfigurationProvider configurationProvider;
-        private final ManageSieveServerFactory manageSieveServerFactory;
-
-        @Inject
-        public ManageSieveModuleInitializationOperation(ConfigurationProvider configurationProvider, ManageSieveServerFactory manageSieveServerFactory) {
-            this.configurationProvider = configurationProvider;
-            this.manageSieveServerFactory = manageSieveServerFactory;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            manageSieveServerFactory.configure(configurationProvider.getConfiguration("managesieveserver", LoggingLevel.INFO));
-            manageSieveServerFactory.init();
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return ManageSieveServerFactory.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation configureManageSieve(ConfigurationProvider configurationProvider, ManageSieveServerFactory manageSieveServerFactory) {
+        return InitilizationOperationBuilder
+            .forClass(ManageSieveServerFactory.class)
+            .init(() -> {
+                manageSieveServerFactory.configure(configurationProvider.getConfiguration("managesieveserver", LoggingLevel.INFO));
+                manageSieveServerFactory.init();
+            });
     }
 }
\ No newline at end of file
diff --git a/server/container/guice/protocols/pop/src/main/java/org/apache/james/modules/protocols/POP3ServerModule.java b/server/container/guice/protocols/pop/src/main/java/org/apache/james/modules/protocols/POP3ServerModule.java
index fd769b2..ad1a808 100644
--- a/server/container/guice/protocols/pop/src/main/java/org/apache/james/modules/protocols/POP3ServerModule.java
+++ b/server/container/guice/protocols/pop/src/main/java/org/apache/james/modules/protocols/POP3ServerModule.java
@@ -19,51 +19,34 @@
 
 package org.apache.james.modules.protocols;
 
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.pop3server.netty.OioPOP3ServerFactory;
 import org.apache.james.pop3server.netty.POP3ServerFactory;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.utils.GuiceProbe;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Scopes;
-import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class POP3ServerModule extends AbstractModule {
-
     @Override
     protected void configure() {
         bind(POP3ServerFactory.class).in(Scopes.SINGLETON);
         bind(OioPOP3ServerFactory.class).in(Scopes.SINGLETON);
 
-        Multibinder.newSetBinder(binder(), InitializationOperation.class).addBinding().to(POP3ModuleInitializationOperation.class);
         Multibinder.newSetBinder(binder(), GuiceProbe.class).addBinding().to(Pop3GuiceProbe.class);
     }
 
-    @Singleton
-    public static class POP3ModuleInitializationOperation implements InitializationOperation {
-        private final ConfigurationProvider configurationProvider;
-        private final POP3ServerFactory pop3ServerFactory;
-
-        @Inject
-        public POP3ModuleInitializationOperation(ConfigurationProvider configurationProvider, POP3ServerFactory pop3ServerFactory) {
-            this.configurationProvider = configurationProvider;
-            this.pop3ServerFactory = pop3ServerFactory;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            pop3ServerFactory.configure(configurationProvider.getConfiguration("pop3server"));
-            pop3ServerFactory.init();
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return POP3ServerFactory.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation configurePop3(ConfigurationProvider configurationProvider, POP3ServerFactory pop3ServerFactory) {
+        return InitilizationOperationBuilder
+            .forClass(POP3ServerFactory.class)
+            .init(() -> {
+                pop3ServerFactory.configure(configurationProvider.getConfiguration("pop3server"));
+                pop3ServerFactory.init();
+            });
     }
-
 }
diff --git a/server/container/guice/protocols/smtp/src/main/java/org/apache/james/modules/protocols/SMTPServerModule.java b/server/container/guice/protocols/smtp/src/main/java/org/apache/james/modules/protocols/SMTPServerModule.java
index 66cdd75..58b2e96 100644
--- a/server/container/guice/protocols/smtp/src/main/java/org/apache/james/modules/protocols/SMTPServerModule.java
+++ b/server/container/guice/protocols/smtp/src/main/java/org/apache/james/modules/protocols/SMTPServerModule.java
@@ -19,59 +19,40 @@
 
 package org.apache.james.modules.protocols;
 
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.smtpserver.SendMailHandler;
 import org.apache.james.smtpserver.netty.OioSMTPServerFactory;
 import org.apache.james.smtpserver.netty.SMTPServerFactory;
 import org.apache.james.utils.GuiceProbe;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Scopes;
-import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class SMTPServerModule extends AbstractModule {
-
     @Override
     protected void configure() {
         install(new JSPFModule());
         bind(SMTPServerFactory.class).in(Scopes.SINGLETON);
         bind(OioSMTPServerFactory.class).in(Scopes.SINGLETON);
 
-        Multibinder.newSetBinder(binder(), InitializationOperation.class).addBinding().to(SMTPModuleInitializationOperation.class);
         Multibinder.newSetBinder(binder(), GuiceProbe.class).addBinding().to(SmtpGuiceProbe.class);
     }
 
-    @Singleton
-    public static class SMTPModuleInitializationOperation implements InitializationOperation {
-
-        private final ConfigurationProvider configurationProvider;
-        private final SMTPServerFactory smtpServerFactory;
-        private final SendMailHandler sendMailHandler;
-
-        @Inject
-        public SMTPModuleInitializationOperation(ConfigurationProvider configurationProvider,
-                                                 SMTPServerFactory smtpServerFactory,
-                                                 SendMailHandler sendMailHandler) {
-            this.configurationProvider = configurationProvider;
-            this.smtpServerFactory = smtpServerFactory;
-            this.sendMailHandler = sendMailHandler;
-        }
-
-        @Override
-        public void initModule() throws Exception {
+    @ProvidesIntoSet
+    InitializationOperation configureSmtp(ConfigurationProvider configurationProvider,
+                                        SMTPServerFactory smtpServerFactory,
+                                        SendMailHandler sendMailHandler) {
+        return InitilizationOperationBuilder
+            .forClass(SMTPServerFactory.class)
+            .init(() -> {
                 smtpServerFactory.configure(configurationProvider.getConfiguration("smtpserver"));
                 smtpServerFactory.init();
                 sendMailHandler.init(null);
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return SMTPServerFactory.class;
-        }
+            });
     }
 
 }
diff --git a/server/container/guice/protocols/webadmin/src/main/java/org/apache/james/modules/server/WebAdminServerModule.java b/server/container/guice/protocols/webadmin/src/main/java/org/apache/james/modules/server/WebAdminServerModule.java
index 87165f1..ff2f263 100644
--- a/server/container/guice/protocols/webadmin/src/main/java/org/apache/james/modules/server/WebAdminServerModule.java
+++ b/server/container/guice/protocols/webadmin/src/main/java/org/apache/james/modules/server/WebAdminServerModule.java
@@ -30,11 +30,11 @@ import javax.inject.Named;
 
 import org.apache.commons.configuration2.Configuration;
 import org.apache.james.jwt.JwtTokenVerifier;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.utils.ClassName;
 import org.apache.james.utils.GuiceGenericLoader;
 import org.apache.james.utils.GuiceProbe;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 import org.apache.james.utils.NamingScheme;
 import org.apache.james.utils.PropertiesProvider;
 import org.apache.james.utils.WebAdminGuiceProbe;
@@ -55,11 +55,11 @@ import com.github.fge.lambdas.Throwing;
 import com.github.steveash.guavate.Guavate;
 import com.google.common.collect.ImmutableList;
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Provides;
 import com.google.inject.Scopes;
 import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class WebAdminServerModule extends AbstractModule {
 
@@ -82,7 +82,6 @@ public class WebAdminServerModule extends AbstractModule {
         bind(JsonTransformer.class).in(Scopes.SINGLETON);
         bind(WebAdminServer.class).in(Scopes.SINGLETON);
 
-        Multibinder.newSetBinder(binder(), InitializationOperation.class).addBinding().to(WebAdminServerModuleInitializationOperation.class);
         Multibinder.newSetBinder(binder(), GuiceProbe.class).addBinding().to(WebAdminGuiceProbe.class);
         Multibinder.newSetBinder(binder(), JsonTransformerModule.class);
     }
@@ -157,24 +156,10 @@ public class WebAdminServerModule extends AbstractModule {
         return Optional.empty();
     }
 
-    @Singleton
-    public static class WebAdminServerModuleInitializationOperation implements InitializationOperation {
-        private final WebAdminServer webAdminServer;
-
-        @Inject
-        public WebAdminServerModuleInitializationOperation(WebAdminServer webAdminServer) {
-            this.webAdminServer = webAdminServer;
-        }
-
-        @Override
-        public void initModule() {
-            webAdminServer.start();
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return WebAdminServer.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation workQueue(WebAdminServer instance) {
+        return InitilizationOperationBuilder
+            .forClass(WebAdminServer.class)
+            .init(instance::start);
     }
-
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org