You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2021/09/18 16:26:34 UTC

[syncope] branch master updated: [SYNCOPE-1618] Use Constructor-level dependency injections (#287)

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

ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git


The following commit(s) were added to refs/heads/master by this push:
     new 6ab0ffc  [SYNCOPE-1618] Use Constructor-level dependency injections (#287)
6ab0ffc is described below

commit 6ab0ffc43370bbfca8253e5ddb0242c27a752fb5
Author: Francesco Chicchiriccò <il...@users.noreply.github.com>
AuthorDate: Sat Sep 18 18:26:16 2021 +0200

    [SYNCOPE-1618] Use Constructor-level dependency injections (#287)
---
 .github/workflows/crosschecks.yml                  |    2 +-
 .../apache/syncope/core/logic/AMLogicContext.java  |  210 ++++
 .../core/logic/AbstractAuthProfileLogic.java       |   12 +-
 .../apache/syncope/core/logic/AuthModuleLogic.java |   14 +-
 .../syncope/core/logic/AuthProfileLogic.java       |    8 +-
 .../apache/syncope/core/logic/ClientAppLogic.java  |   44 +-
 .../apache/syncope/core/logic/OIDCJWKSLogic.java   |   14 +-
 .../syncope/core/logic/SAML2IdPEntityLogic.java    |   14 +-
 .../syncope/core/logic/SAML2SPEntityLogic.java     |   14 +-
 .../apache/syncope/core/logic/SRARouteLogic.java   |   32 +-
 .../core/logic/init/AMEntitlementLoader.java       |    2 -
 .../core/logic/wa/GoogleMfaAuthAccountLogic.java   |   41 +-
 .../core/logic/wa/GoogleMfaAuthTokenLogic.java     |   17 +-
 .../syncope/core/logic/wa/ImpersonationLogic.java  |   17 +-
 .../core/logic/wa/U2FRegistrationLogic.java        |   17 +-
 .../syncope/core/logic/wa/WAClientAppLogic.java    |   31 +-
 .../syncope/core/logic/wa/WAConfigLogic.java       |   27 +-
 .../core/logic/wa/WebAuthnRegistrationLogic.java   |   17 +-
 .../src/main/resources/META-INF/spring.factories   |    2 +-
 .../syncope/core/rest/cxf/AMRESTCXFContext.java    |  174 ++++
 .../rest/cxf/service/AuthModuleServiceImpl.java    |   10 +-
 .../rest/cxf/service/AuthProfileServiceImpl.java   |   10 +-
 .../rest/cxf/service/ClientAppServiceImpl.java     |   10 +-
 .../core/rest/cxf/service/OIDCJWKSServiceImpl.java |   10 +-
 .../cxf/service/SAML2IdPEntityServiceImpl.java     |   10 +-
 .../rest/cxf/service/SAML2SPEntityServiceImpl.java |   10 +-
 .../core/rest/cxf/service/SRARouteServiceImpl.java |   10 +-
 .../wa/GoogleMfaAuthAccountServiceImpl.java        |   12 +-
 .../service/wa/GoogleMfaAuthTokenServiceImpl.java  |   12 +-
 .../cxf/service/wa/ImpersonationServiceImpl.java   |   12 +-
 .../cxf/service/wa/U2FRegistrationServiceImpl.java |   12 +-
 .../cxf/service/wa/WAClientAppServiceImpl.java     |   12 +-
 .../rest/cxf/service/wa/WAConfigServiceImpl.java   |   12 +-
 .../wa/WebAuthnRegistrationServiceImpl.java        |   12 +-
 .../src/main/resources/META-INF/spring.factories   |    2 +-
 .../apache/syncope/core/logic/ConnectorLogic.java  |   66 +-
 .../apache/syncope/core/logic/IdMLogicContext.java |  162 ++++
 .../syncope/core/logic/ReconciliationLogic.java    |  119 ++-
 .../syncope/core/logic/RemediationLogic.java       |   32 +-
 .../apache/syncope/core/logic/ResourceLogic.java   |   98 +-
 .../core/logic/init/IdMEntitlementLoader.java      |    2 -
 .../logic/init/IdMImplementationTypeLoader.java    |    2 -
 .../src/main/resources/META-INF/spring.factories   |    2 +-
 .../syncope/core/logic/DummyConfParamOps.java      |    2 -
 .../apache/syncope/core/logic/DummyDomainOps.java  |   10 +-
 .../apache/syncope/core/logic/DummyServiceOps.java |    2 -
 .../syncope/core/logic/IdMLogicTestContext.java    |   44 +-
 .../apache/syncope/core/logic/TestInitializer.java |   32 +-
 .../syncope/core/rest/cxf/IdMRESTCXFContext.java   |   80 ++
 .../rest/cxf/service/ConnectorServiceImpl.java     |   10 +-
 .../cxf/service/ReconciliationServiceImpl.java     |   12 +-
 .../rest/cxf/service/RemediationServiceImpl.java   |   27 +-
 .../core/rest/cxf/service/ResourceServiceImpl.java |   10 +-
 .../src/main/resources/META-INF/spring.factories   |    2 +-
 .../syncope/core/logic/AbstractAnyLogic.java       |   22 +-
 .../core/logic/AbstractExecutableLogic.java        |    6 +
 .../syncope/core/logic/AbstractJobLogic.java       |   12 +-
 .../syncope/core/logic/AccessTokenLogic.java       |   32 +-
 .../apache/syncope/core/logic/AnyObjectLogic.java  |   35 +-
 .../syncope/core/logic/AnyTypeClassLogic.java      |   14 +-
 .../apache/syncope/core/logic/AnyTypeLogic.java    |   22 +-
 .../syncope/core/logic/ApplicationLogic.java       |   14 +-
 .../org/apache/syncope/core/logic/AuditLogic.java  |   76 +-
 .../apache/syncope/core/logic/DelegationLogic.java |   24 +-
 .../apache/syncope/core/logic/DynRealmLogic.java   |   14 +-
 .../org/apache/syncope/core/logic/GroupLogic.java  |   80 +-
 .../syncope/core/logic/IdRepoLogicContext.java     |  515 ++++++++++
 .../syncope/core/logic/ImplementationLogic.java    |   54 +-
 .../syncope/core/logic/LogicInvocationHandler.java |   14 +-
 .../apache/syncope/core/logic/LogicProperties.java |   22 -
 .../syncope/core/logic/MailTemplateLogic.java      |   24 +-
 .../syncope/core/logic/NotificationLogic.java      |   22 +-
 .../org/apache/syncope/core/logic/PolicyLogic.java |   22 +-
 .../org/apache/syncope/core/logic/RealmLogic.java  |   32 +-
 .../syncope/core/logic/RelationshipTypeLogic.java  |   17 +-
 .../org/apache/syncope/core/logic/ReportLogic.java |   38 +-
 .../syncope/core/logic/ReportTemplateLogic.java    |   24 +-
 .../org/apache/syncope/core/logic/RoleLogic.java   |   14 +-
 .../org/apache/syncope/core/logic/SchemaLogic.java |   34 +-
 .../syncope/core/logic/SecurityQuestionLogic.java  |   22 +-
 .../apache/syncope/core/logic/SyncopeLogic.java    |   52 +-
 .../org/apache/syncope/core/logic/TaskLogic.java   |   58 +-
 .../org/apache/syncope/core/logic/UserLogic.java   |   60 +-
 .../syncope/core/logic/init/AuditAccessor.java     |   12 +-
 .../syncope/core/logic/init/AuditLoader.java       |   22 +-
 .../core/logic/init/EntitlementAccessor.java       |   10 +-
 .../core/logic/init/IdRepoEntitlementLoader.java   |   10 +-
 .../logic/init/IdRepoImplementationTypeLoader.java |    2 -
 .../src/main/resources/META-INF/spring.factories   |    2 +-
 .../syncope/core/rest/cxf/CheckDomainFilter.java   |    8 +-
 .../core/rest/cxf/IdRepoRESTCXFContext.java        |  509 ++++++++++
 .../syncope/core/rest/cxf/RESTCXFContext.java      |  233 -----
 .../core/rest/cxf/RestServiceExceptionMapper.java  |   14 +-
 .../core/rest/cxf/service/AbstractAnyService.java  |   10 +-
 .../cxf/service/AbstractExecutableService.java     |    2 +-
 .../rest/cxf/service/AbstractSearchService.java    |   55 ++
 ...stractServiceImpl.java => AbstractService.java} |   30 +-
 .../rest/cxf/service/AccessTokenServiceImpl.java   |   10 +-
 .../rest/cxf/service/AnyObjectServiceImpl.java     |   18 +-
 .../rest/cxf/service/AnyTypeClassServiceImpl.java  |   10 +-
 .../core/rest/cxf/service/AnyTypeServiceImpl.java  |   10 +-
 .../rest/cxf/service/ApplicationServiceImpl.java   |   10 +-
 .../core/rest/cxf/service/AuditServiceImpl.java    |   10 +-
 .../rest/cxf/service/DelegationServiceImpl.java    |   10 +-
 .../core/rest/cxf/service/DynRealmServiceImpl.java |   10 +-
 .../core/rest/cxf/service/GroupServiceImpl.java    |   18 +-
 .../cxf/service/ImplementationServiceImpl.java     |   10 +-
 .../rest/cxf/service/MailTemplateServiceImpl.java  |   10 +-
 .../rest/cxf/service/NotificationServiceImpl.java  |   10 +-
 .../core/rest/cxf/service/PolicyServiceImpl.java   |   10 +-
 .../core/rest/cxf/service/RealmServiceImpl.java    |   10 +-
 .../cxf/service/RelationshipTypeServiceImpl.java   |   10 +-
 .../core/rest/cxf/service/ReportServiceImpl.java   |    8 +-
 .../cxf/service/ReportTemplateServiceImpl.java     |   10 +-
 .../core/rest/cxf/service/RoleServiceImpl.java     |   10 +-
 .../core/rest/cxf/service/SchemaServiceImpl.java   |   10 +-
 .../cxf/service/SecurityQuestionServiceImpl.java   |   10 +-
 .../core/rest/cxf/service/SyncopeServiceImpl.java  |   33 +-
 .../core/rest/cxf/service/TaskServiceImpl.java     |    8 +-
 .../core/rest/cxf/service/UserSelfServiceImpl.java |   14 +-
 .../core/rest/cxf/service/UserServiceImpl.java     |   18 +-
 .../src/main/resources/META-INF/spring.factories   |    2 +-
 .../rest/cxf/service/AnyObjectServiceTest.java     |    7 +-
 ...tContext.java => IdRepoRESTCXFTestContext.java} |    9 +-
 core/persistence-jpa-json/pom.xml                  |    5 +-
 .../persistence/jpa/JPAJSONPersistenceContext.java |  155 +++
 .../jpa/MyJPAJSONPersistenceContext.java           |  101 ++
 .../jpa/PGJPAJSONPersistenceContext.java           |  101 ++
 .../persistence/jpa/dao/AbstractJPAJSONAnyDAO.java |    8 +-
 .../jpa/dao/AbstractJPAJSONPlainSchemaDAO.java     |   11 +
 .../persistence/jpa/dao/JPAJSONAnyObjectDAO.java   |   35 +-
 .../core/persistence/jpa/dao/JPAJSONGroupDAO.java  |   53 +-
 .../core/persistence/jpa/dao/JPAJSONUserDAO.java   |   57 +-
 .../core/persistence/jpa/dao/MyJPAJSONAnyDAO.java  |    5 +
 .../persistence/jpa/dao/MyJPAJSONAnySearchDAO.java |   21 +
 .../jpa/dao/MyJPAJSONPlainSchemaDAO.java           |   11 +
 .../core/persistence/jpa/dao/PGJPAJSONAnyDAO.java  |    5 +
 .../persistence/jpa/dao/PGJPAJSONAnySearchDAO.java |   25 +-
 .../jpa/dao/PGJPAJSONPlainSchemaDAO.java           |   11 +
 .../jpa/entity/JPAJSONEntityFactory.java           |   25 +-
 .../jpa/entity/MyJPAJSONEntityFactory.java         |    7 -
 .../jpa/entity/PGJPAJSONEntityFactory.java         |    7 -
 .../src/main/resources/META-INF/spring.factories   |    3 +-
 .../src/main/resources/core-myjson.properties      |   14 -
 .../src/main/resources/core-pgjsonb.properties     |   11 -
 .../jpa/JPAJSONTestContextCustomizer.java          |   58 ++
 .../jpa/JPAJSONTestContextCustomizerFactory.java}  |   19 +-
 .../src/test}/resources/META-INF/spring.factories  |    4 +-
 .../src/test/resources/domains/MasterContent.xml   |    2 +-
 .../src/test/resources/simplelogger.properties     |    1 -
 .../core/persistence/jpa/DomainConfFactory.java    |   28 +-
 .../syncope/core/persistence/jpa/MasterDomain.java |   13 +-
 .../core/persistence/jpa/PersistenceContext.java   |  609 +++++++++++-
 .../persistence/jpa/PersistenceProperties.java     |  119 ---
 .../core/persistence/jpa/RuntimeDomainLoader.java  |   16 +-
 .../core/persistence/jpa/StartupDomainLoader.java  |   34 +-
 .../jpa/content/KeymasterConfParamLoader.java      |   16 +-
 .../jpa/content/XMLContentExporter.java            |   44 +-
 .../persistence/jpa/content/XMLContentLoader.java  |   30 +-
 .../core/persistence/jpa/dao/AbstractAnyDAO.java   |   34 +-
 .../persistence/jpa/dao/AbstractAnySearchDAO.java  |   63 +-
 .../core/persistence/jpa/dao/AbstractDAO.java      |    2 -
 .../persistence/jpa/dao/JPAAccessTokenDAO.java     |    2 -
 .../core/persistence/jpa/dao/JPAAnyMatchDAO.java   |   72 +-
 .../core/persistence/jpa/dao/JPAAnyObjectDAO.java  |   26 +-
 .../core/persistence/jpa/dao/JPAAnySearchDAO.java  |   23 +-
 .../persistence/jpa/dao/JPAAnyTypeClassDAO.java    |   37 +-
 .../core/persistence/jpa/dao/JPAAnyTypeDAO.java    |   10 +-
 .../persistence/jpa/dao/JPAApplicationDAO.java     |   14 +-
 .../core/persistence/jpa/dao/JPABatchDAO.java      |    2 -
 .../persistence/jpa/dao/JPAConnInstanceDAO.java    |   29 +-
 .../core/persistence/jpa/dao/JPADelegationDAO.java |    2 -
 .../core/persistence/jpa/dao/JPADerSchemaDAO.java  |   12 +-
 .../core/persistence/jpa/dao/JPADynRealmDAO.java   |   46 +-
 .../jpa/dao/JPAExternalResourceDAO.java            |   89 +-
 .../core/persistence/jpa/dao/JPAGroupDAO.java      |   60 +-
 .../persistence/jpa/dao/JPAImplementationDAO.java  |    2 -
 .../persistence/jpa/dao/JPAMailTemplateDAO.java    |    2 -
 .../persistence/jpa/dao/JPANotificationDAO.java    |   10 +-
 .../core/persistence/jpa/dao/JPAPlainAttrDAO.java  |    4 +-
 .../persistence/jpa/dao/JPAPlainSchemaDAO.java     |   22 +-
 .../core/persistence/jpa/dao/JPAPolicyDAO.java     |   23 +-
 .../core/persistence/jpa/dao/JPARealmDAO.java      |   12 +-
 .../jpa/dao/JPARelationshipTypeDAO.java            |    2 -
 .../persistence/jpa/dao/JPARemediationDAO.java     |    2 -
 .../core/persistence/jpa/dao/JPAReportDAO.java     |    2 -
 .../core/persistence/jpa/dao/JPAReportExecDAO.java |    2 -
 .../persistence/jpa/dao/JPAReportTemplateDAO.java  |    2 -
 .../core/persistence/jpa/dao/JPARoleDAO.java       |   34 +-
 .../core/persistence/jpa/dao/JPASRARouteDAO.java   |    2 -
 .../jpa/dao/JPASecurityQuestionDAO.java            |   10 +-
 .../core/persistence/jpa/dao/JPATaskDAO.java       |   48 +-
 .../core/persistence/jpa/dao/JPATaskExecDAO.java   |   14 +-
 .../core/persistence/jpa/dao/JPAUserDAO.java       |   46 +-
 .../core/persistence/jpa/dao/JPAVirSchemaDAO.java  |   12 +-
 .../persistence/jpa/dao/auth/JPAAuthModuleDAO.java |    2 -
 .../jpa/dao/auth/JPAAuthProfileDAO.java            |    2 -
 .../core/persistence/jpa/dao/auth/JPACASSPDAO.java |    2 -
 .../persistence/jpa/dao/auth/JPAOIDCJWKSDAO.java   |    8 +-
 .../persistence/jpa/dao/auth/JPAOIDCRPDAO.java     |    2 -
 .../jpa/dao/auth/JPASAML2IdPEntityDAO.java         |    2 -
 .../persistence/jpa/dao/auth/JPASAML2SPDAO.java    |    2 -
 .../jpa/dao/auth/JPASAML2SPEntityDAO.java          |    2 -
 .../persistence/jpa/dao/auth/JPAWAConfigDAO.java   |    2 -
 .../core/persistence/jpa/entity/JPAAnyUtils.java   |   42 +-
 .../persistence/jpa/entity/JPAAnyUtilsFactory.java |   36 +-
 .../jpa/entity/auth/JPAClientAppUtilsFactory.java  |    2 -
 .../jpa/entity/policy/JPAPolicyUtilsFactory.java   |    2 -
 .../persistence/jpa/entity/task/JPATaskUtils.java  |    9 +-
 .../jpa/entity/task/JPATaskUtilsFactory.java       |   14 +-
 .../core/persistence/jpa/DummyConfParamOps.java    |    2 -
 .../persistence/jpa/DummyConnectorManager.java     |   73 ++
 .../core/persistence/jpa/DummyDomainOps.java       |   10 +-
 .../persistence/jpa/DummyImplementationLookup.java |    2 -
 .../persistence/jpa/PersistenceTestContext.java    |   41 +
 .../core/persistence/jpa/TestInitializer.java      |   32 +-
 .../src/test/resources/domains/MasterContent.xml   |    2 +-
 ...ConnectorFactory.java => ConnectorManager.java} |   16 +-
 .../core/provisioning/api/ConnectorRegistry.java   |   41 -
 .../core/provisioning/api/IntAttrNameParser.java   |   45 +-
 .../api/pushpull/SyncopeSinglePushExecutor.java    |    6 +-
 .../provisioning/api/IntAttrNameParserTest.java    |    4 +-
 .../provisioning/java/AsyncConnectorFacade.java    |    2 -
 .../core/provisioning/java/ConnectorLoader.java    |   14 +-
 .../java/DefaultAnyObjectProvisioningManager.java  |   30 +-
 .../provisioning/java/DefaultAuditManager.java     |   22 +-
 ...erImpl.java => DefaultConnIdBundleManager.java} |   15 +-
 ...orManager.java => DefaultConnectorManager.java} |   57 +-
 ...HandlerImpl.java => DefaultDerAttrHandler.java} |   22 +-
 .../java/DefaultGroupProvisioningManager.java      |   35 +-
 ...ManagerImpl.java => DefaultMappingManager.java} |   88 +-
 .../java/DefaultUserProvisioningManager.java       |   30 +-
 ...HandlerImpl.java => DefaultVirAttrHandler.java} |   37 +-
 .../provisioning/java/ProvisioningContext.java     | 1023 ++++++++++++++++++--
 .../provisioning/java/ProvisioningProperties.java  |   97 --
 .../java/data/AbstractAnyDataBinder.java           |   95 +-
 .../java/data/AccessTokenDataBinderImpl.java       |   37 +-
 .../java/data/AnyObjectDataBinderImpl.java         |   61 +-
 .../java/data/AnyTypeClassDataBinderImpl.java      |   34 +-
 .../java/data/AnyTypeDataBinderImpl.java           |   36 +-
 .../java/data/ApplicationDataBinderImpl.java       |   16 +-
 .../java/data/AuditDataBinderImpl.java             |    2 -
 .../java/data/AuthModuleDataBinderImpl.java        |   16 +-
 .../java/data/AuthProfileDataBinderImpl.java       |   10 +-
 .../java/data/ClientAppDataBinderImpl.java         |   36 +-
 .../java/data/ConnInstanceDataBinderImpl.java      |   37 +-
 .../java/data/DelegationDataBinderImpl.java        |   24 +-
 .../java/data/DynRealmDataBinderImpl.java          |   36 +-
 .../java/data/GroupDataBinderImpl.java             |   73 +-
 .../java/data/ImplementationDataBinderImpl.java    |   12 +-
 .../java/data/NotificationDataBinderImpl.java      |   34 +-
 .../java/data/OIDCJWKSDataBinderImpl.java          |   12 +-
 .../java/data/PolicyDataBinderImpl.java            |   36 +-
 .../java/data/RealmDataBinderImpl.java             |   41 +-
 .../java/data/RelationshipTypeDataBinderImpl.java  |   13 +-
 .../java/data/RemediationDataBinderImpl.java       |    2 -
 .../java/data/ReportDataBinderImpl.java            |   29 +-
 .../java/data/ResourceDataBinderImpl.java          |   58 +-
 .../provisioning/java/data/RoleDataBinderImpl.java |   41 +-
 .../java/data/SAML2IdPEntityDataBinderImpl.java    |   10 +-
 .../java/data/SAML2SPEntityDataBinderImpl.java     |   10 +-
 .../java/data/SRARouteDataBinderImpl.java          |    2 -
 .../java/data/SchemaDataBinderImpl.java            |   64 +-
 .../java/data/SecurityQuestionDataBinderImpl.java  |   10 +-
 .../provisioning/java/data/TaskDataBinderImpl.java |   58 +-
 .../provisioning/java/data/UserDataBinderImpl.java |  111 ++-
 .../java/data/WAConfigDataBinderImpl.java          |   14 +-
 .../java/data/wa/WAClientAppDataBinderImpl.java    |   24 +-
 ...{JobManagerImpl.java => DefaultJobManager.java} |   58 +-
 .../java/job/SystemLoadReporterJob.java            |   12 +-
 .../core/provisioning/java/job/TaskJob.java        |    2 +-
 .../DefaultNotificationJobDelegate.java            |   44 +-
 .../java/job/notification/NotificationJob.java     |   24 +-
 .../java/job/report/DefaultReportJobDelegate.java  |   38 +-
 .../java/job/report/ReconciliationReportlet.java   |    6 +-
 .../notification/DefaultNotificationManager.java   |  135 +--
 .../AbstractPropagationTaskExecutor.java           |  106 +-
 .../propagation/DefaultPropagationManager.java     |   42 +-
 .../PriorityPropagationTaskExecutor.java           |   54 +-
 .../pushpull/AbstractProvisioningJobDelegate.java  |    6 +-
 .../{ => pushpull}/DefaultProvisionSorter.java     |    3 +-
 .../pushpull/DefaultUserPushResultHandler.java     |   24 +-
 .../provisioning/java/pushpull/InboundMatcher.java |   64 +-
 .../java/pushpull/OutboundMatcher.java             |   52 +-
 .../java/pushpull/PullJobDelegate.java             |    1 -
 .../java/pushpull/PushJobDelegate.java             |    1 -
 .../java/pushpull/SinglePushJobDelegate.java       |   14 +-
 .../stream/StreamAnyObjectPushResultHandler.java   |    8 +-
 .../stream/StreamGroupPushResultHandler.java       |    8 +-
 .../pushpull/stream/StreamPushJobDelegate.java     |   23 +-
 .../stream/StreamUserPushResultHandler.java        |    8 +-
 .../provisioning/java/utils/ConnObjectUtils.java   |   62 +-
 .../provisioning/java/utils/TemplateUtils.java     |   26 +-
 .../provisioning/java/ConnectorManagerTest.java    |    7 +-
 ...mplTest.java => DefaultMappingManagerTest.java} |    2 +-
 .../core/provisioning/java/DummyConfParamOps.java  |    2 -
 .../core/provisioning/java/DummyDomainOps.java     |   10 +-
 .../java/DummyImplementationLookup.java            |    2 -
 .../provisioning/java/ProvisioningTestContext.java |   41 +-
 .../core/provisioning/java/TestInitializer.java    |   32 +-
 core/self-keymaster-starter/pom.xml                |    4 +-
 .../SelfKeymasterInternalConfParamOps.java         |   16 +-
 .../internal/SelfKeymasterInternalDomainOps.java   |   12 +-
 .../internal/SelfKeymasterInternalServiceOps.java  |   12 +-
 .../rest/cxf/service/ConfParamServiceImpl.java     |   12 +-
 .../rest/cxf/service/DomainServiceImpl.java        |   10 +-
 .../cxf/service/NetworkServiceServiceImpl.java     |    8 +-
 ...sterUsernamePasswordAuthenticationProvider.java |   31 +-
 .../apache/syncope/core/logic/ConfParamLogic.java  |   16 +-
 .../org/apache/syncope/core/logic/DomainLogic.java |   22 +-
 .../syncope/core/logic/NetworkServiceLogic.java    |   16 +-
 .../core/persistence/jpa/dao/JPAConfParamDAO.java  |    2 -
 .../core/persistence/jpa/dao/JPADomainDAO.java     |    2 -
 .../persistence/jpa/dao/JPANetworkServiceDAO.java  |    2 -
 .../jpa/entity/JPASelfKeymasterEntityFactory.java  |    2 -
 .../syncope/core/starter/SelfKeymasterContext.java |  140 ++-
 .../core/spring/security/AuthDataAccessor.java     |   81 +-
 .../spring/security/DefaultPasswordGenerator.java  |   27 +-
 .../spring/security/JWTAuthenticationProvider.java |    8 +-
 .../core/spring/security/SecurityContext.java      |    8 +-
 .../core/spring/security/SecurityProperties.java   |   10 -
 .../UsernamePasswordAuthenticationProvider.java    |   30 +-
 .../core/spring/security/WebSecurityContext.java   |   75 +-
 .../core/starter/SyncopeCoreApplication.java       |    7 +-
 .../syncope/core/starter/SyncopeCoreStart.java     |    7 +-
 .../actuate/ExternalResourcesHealthIndicator.java  |    8 +-
 .../actuate/SyncopeCoreInfoContributor.java        |    5 -
 core/starter/src/main/resources/core.properties    |   30 -
 .../java/AbstractAnyObjectWorkflowAdapter.java     |   20 +-
 .../java/AbstractGroupWorkflowAdapter.java         |   20 +-
 .../workflow/java/AbstractUserWorkflowAdapter.java |   20 +-
 .../java/DefaultAnyObjectWorkflowAdapter.java      |   11 +
 .../workflow/java/DefaultGroupWorkflowAdapter.java |   11 +
 .../workflow/java/DefaultUserWorkflowAdapter.java  |   17 +-
 .../core/workflow/java/WorkflowContext.java        |   46 +-
 .../core/workflow/java/WorkflowProperties.java     |   58 --
 .../core/src/main/resources/core-myjson.properties |   14 -
 .../src/main/resources/core-pgjsonb.properties     |   11 -
 .../syncope/core/logic/CamelLogicContext.java      |   40 +-
 .../apache/syncope/core/logic/CamelRouteLogic.java |   24 +-
 .../syncope/core/logic/init/CamelRouteLoader.java  |   29 +-
 .../src/main/resources/META-INF/spring.factories   |    2 +-
 .../persistence/jpa/CamelPersistenceContext.java}  |   28 +-
 .../core/persistence/jpa/dao/JPACamelRouteDAO.java |    2 -
 .../jpa/entity/JPACamelEntityFactory.java          |    3 -
 .../src/main/resources/META-INF/spring.factories   |    2 +-
 .../camel/AbstractCamelProvisioningManager.java    |   12 +-
 .../camel/CamelAnyObjectProvisioningManager.java   |    7 +-
 .../camel/CamelGroupProvisioningManager.java       |    7 +-
 .../camel/CamelProvisioningContext.java            |   92 ++
 .../camel/CamelUserProvisioningManager.java        |    5 +
 .../provisioning/camel/SyncopeCamelContext.java    |   16 +-
 .../camel/data/CamelRouteDataBinderImpl.java       |   10 +-
 .../src/main/resources/META-INF/spring.factories   |    2 +-
 .../src/main/resources/core-camel.properties       |   20 -
 .../core/rest/cxf/CamelRESTCXFContext.java}        |   29 +-
 .../rest/cxf/service/CamelRouteServiceImpl.java    |   11 +-
 .../src/main/resources/META-INF/spring.factories   |    2 +-
 .../client/ElasticsearchClientContext.java         |   29 +-
 .../client/ElasticsearchIndexManager.java          |   15 +-
 .../elasticsearch/client/ElasticsearchUtils.java   |   16 +-
 .../core/persistence/jpa/DomainIndexLoader.java    |   12 +-
 .../jpa/ElasticsearchPersistenceContext.java       |   77 ++
 .../jpa/dao/ElasticsearchAnySearchDAO.java         |   36 +-
 .../src/main/resources/META-INF/spring.factories   |    2 +-
 .../main/resources/core-elasticsearch.properties   |   18 -
 ...leContext.java => FlowableWorkflowContext.java} |  139 ++-
 .../flowable/impl/FlowableBpmnProcessManager.java  |    8 +-
 .../flowable/impl/FlowableUserRequestHandler.java  |   31 +-
 .../flowable/impl/FlowableUserWorkflowAdapter.java |   22 +-
 .../core/flowable/impl/FlowableWorkflowUtils.java  |   10 +-
 .../support/DomainProcessEngineFactoryBean.java    |   17 +-
 .../syncope/core/flowable/task/AutoActivate.java   |   14 +-
 .../apache/syncope/core/flowable/task/Create.java  |   14 +-
 .../apache/syncope/core/flowable/task/Delete.java  |    2 -
 .../core/flowable/task/FlowableServiceTask.java    |    2 -
 .../syncope/core/flowable/task/GenerateToken.java  |   10 +-
 .../apache/syncope/core/flowable/task/Notify.java  |   10 +-
 .../syncope/core/flowable/task/PasswordReset.java  |   14 +-
 .../syncope/core/flowable/task/Reactivate.java     |    2 -
 .../apache/syncope/core/flowable/task/Suspend.java |    2 -
 .../apache/syncope/core/flowable/task/Update.java  |   14 +-
 .../src/main/resources/META-INF/spring.factories   |    2 +-
 .../src/main/resources/core-flowable.properties    |    1 -
 .../syncope/core/logic/BpmnProcessLogic.java       |   10 +-
 .../syncope/core/logic/FlowableLogicContext.java   |   89 ++
 .../syncope/core/logic/UserRequestLogic.java       |   39 +-
 .../syncope/core/logic/UserWorkflowTaskLogic.java  |   34 +-
 .../syncope/core/logic/init/FlowableLoader.java    |   16 +-
 .../src/main/resources/META-INF/spring.factories   |    2 +-
 .../core/rest/cxf/FlowableRESTCXFContext.java      |   59 ++
 .../rest/cxf/service/BpmnProcessServiceImpl.java   |   10 +-
 .../rest/cxf/service/UserRequestServiceImpl.java   |   14 +-
 .../cxf/service/UserWorkflowTaskServiceImpl.java   |   10 +-
 .../src/main/resources/META-INF/spring.factories   |    2 +-
 .../apache/syncope/core/logic/OIDCC4UILogic.java   |   44 +-
 .../syncope/core/logic/OIDCC4UILogicContext.java   |   98 ++
 .../syncope/core/logic/OIDCC4UIProviderLogic.java  |   22 +-
 .../syncope/core/logic/init/OIDCC4UILoader.java    |    2 -
 .../core/logic/model/TokenEndpointResponse.java    |   85 --
 .../syncope/core/logic/oidc/OIDCClientCache.java   |    6 +-
 .../syncope/core/logic/oidc/OIDCUserManager.java   |   43 +-
 .../src/main/resources/META-INF/spring.factories   |    2 +-
 .../jpa/OIDCC4UIPersistenceContext.java}           |   24 +-
 .../jpa/dao/JPAOIDCC4UIProviderDAO.java            |    2 -
 .../jpa/entity/JPAOIDCC4UIEntityFactory.java       |    2 -
 .../src/main/resources/META-INF/spring.factories   |    2 +-
 .../java/data/OIDCC4UIProviderDataBinderImpl.java  |   32 +-
 .../java/data/OIDCC4UIProvisioningContext.java     |   52 +
 .../src/main/resources/META-INF/spring.factories   |    2 +-
 .../core/rest/cxf/OIDCC4UIRESTCXFContext.java}     |   36 +-
 .../cxf/service/OIDCC4UIProviderServiceImpl.java   |   10 +-
 .../core/rest/cxf/service/OIDCC4UIServiceImpl.java |   10 +-
 .../src/main/resources/META-INF/spring.factories   |    2 +-
 .../syncope/core/logic/SAML2SP4UIIdPLogic.java     |   27 +-
 .../apache/syncope/core/logic/SAML2SP4UILogic.java |   59 +-
 .../syncope/core/logic/SAML2SP4UILogicContext.java |  114 +++
 .../syncope/core/logic/init/SAML2SP4UILoader.java  |   14 +-
 .../syncope/core/logic/saml2/SAML2ClientCache.java |    8 +-
 .../core/logic/saml2/SAML2SP4UIUserManager.java    |   42 +-
 .../src/main/resources/META-INF/spring.factories   |    2 +-
 .../jpa/SAML2SP4UIPersistenceContext.java}         |   31 +-
 .../persistence/jpa/dao/JPASAML2SP4UIIdPDAO.java   |    2 -
 .../jpa/entity/JPASAML2SP4UIEntityFactory.java     |    2 -
 .../src/main/resources/META-INF/spring.factories   |    2 +-
 .../java/SAML2SP4UIProvisioningContext.java        |   53 +
 .../java/data/SAML2SP4UIIdPDataBinderImpl.java     |   38 +-
 .../src/main/resources/META-INF/spring.factories   |    2 +-
 .../core/rest/cxf/SAML2SP4UIRESTCXFContext.java}   |   36 +-
 .../rest/cxf/service/SAML2SP4UIIdPServiceImpl.java |   10 +-
 .../rest/cxf/service/SAML2SP4UIServiceImpl.java    |   10 +-
 .../src/main/resources/META-INF/spring.factories   |    2 +-
 .../apache/syncope/core/logic/SCIMDataBinder.java  |   38 +-
 .../org/apache/syncope/core/logic/SCIMLogic.java   |   26 +-
 .../syncope/core/logic/SCIMLogicContext.java       |   42 +-
 .../apache/syncope/core/logic/init/SCIMLoader.java |    2 -
 .../syncope/core/logic/scim/SCIMConfManager.java   |   14 +-
 .../src/main/resources/META-INF/spring.factories   |    2 +-
 .../syncope/core/rest/cxf/SCIMRESTCXFContext.java  |   19 +-
 .../core/rest/cxf/service/SCIMConfServiceImpl.java |   10 +-
 .../src/main/resources/META-INF/spring.factories   |    2 +-
 .../syncope/ext/scimv2/cxf/AddETagFilter.java      |    2 +-
 ...IMCXFContext.java => SCIMv2RESTCXFContext.java} |   65 +-
 .../ext/scimv2/cxf/service/AbstractService.java    |   95 +-
 .../ext/scimv2/cxf/service/GroupServiceImpl.java   |   40 +-
 .../ext/scimv2/cxf/service/SCIMServiceImpl.java    |   34 +-
 .../ext/scimv2/cxf/service/UserServiceImpl.java    |   32 +-
 .../src/main/resources/META-INF/spring.factories   |    2 +-
 .../fit/core/reference/CoreReferenceContext.java   |   66 ++
 .../core/reference}/ElasticsearchInit.java         |   24 +-
 .../reference}/EnableFlowableForTestUsers.java     |   12 +-
 .../fit/core/reference/ITImplementationLookup.java |  132 +--
 .../src/main/resources/META-INF/spring.factories   |    2 +-
 .../src/main/resources/core-all.properties         |    6 -
 .../src/main/resources/core-myjson.properties      |   14 -
 .../src/main/resources/core-pgjsonb.properties     |   11 -
 .../syncope/fit/core/AuthenticationITCase.java     |    8 +
 .../org/apache/syncope/fit/core/GroupITCase.java   |   21 +-
 pom.xml                                            |    2 +-
 .../bootstrap/SyncopeWAPropertySourceLocator.java  |    1 +
 460 files changed, 9688 insertions(+), 4446 deletions(-)

diff --git a/.github/workflows/crosschecks.yml b/.github/workflows/crosschecks.yml
index 55a5f4d..0fa8c5b 100644
--- a/.github/workflows/crosschecks.yml
+++ b/.github/workflows/crosschecks.yml
@@ -33,7 +33,7 @@ jobs:
       fail-fast: false
       matrix:
         language: ['java']
-        java: [ '11', '14', '17-ea' ]
+        java: [ '11', '14', '17' ]
         os: [ubuntu-latest, windows-latest, macos-latest]
 
     steps:
diff --git a/core/am/logic/src/main/java/org/apache/syncope/core/logic/AMLogicContext.java b/core/am/logic/src/main/java/org/apache/syncope/core/logic/AMLogicContext.java
new file mode 100644
index 0000000..cf6e357
--- /dev/null
+++ b/core/am/logic/src/main/java/org/apache/syncope/core/logic/AMLogicContext.java
@@ -0,0 +1,210 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.logic;
+
+import org.apache.syncope.common.keymaster.client.api.ServiceOps;
+import org.apache.syncope.core.logic.init.AMEntitlementLoader;
+import org.apache.syncope.core.logic.wa.GoogleMfaAuthAccountLogic;
+import org.apache.syncope.core.logic.wa.GoogleMfaAuthTokenLogic;
+import org.apache.syncope.core.logic.wa.ImpersonationLogic;
+import org.apache.syncope.core.logic.wa.U2FRegistrationLogic;
+import org.apache.syncope.core.logic.wa.WAClientAppLogic;
+import org.apache.syncope.core.logic.wa.WAConfigLogic;
+import org.apache.syncope.core.logic.wa.WebAuthnRegistrationLogic;
+import org.apache.syncope.core.persistence.api.dao.SRARouteDAO;
+import org.apache.syncope.core.persistence.api.dao.auth.AuthModuleDAO;
+import org.apache.syncope.core.persistence.api.dao.auth.AuthProfileDAO;
+import org.apache.syncope.core.persistence.api.dao.auth.CASSPDAO;
+import org.apache.syncope.core.persistence.api.dao.auth.OIDCJWKSDAO;
+import org.apache.syncope.core.persistence.api.dao.auth.OIDCRPDAO;
+import org.apache.syncope.core.persistence.api.dao.auth.SAML2IdPEntityDAO;
+import org.apache.syncope.core.persistence.api.dao.auth.SAML2SPDAO;
+import org.apache.syncope.core.persistence.api.dao.auth.SAML2SPEntityDAO;
+import org.apache.syncope.core.persistence.api.dao.auth.WAConfigDAO;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.auth.ClientAppUtilsFactory;
+import org.apache.syncope.core.provisioning.api.data.AuthModuleDataBinder;
+import org.apache.syncope.core.provisioning.api.data.AuthProfileDataBinder;
+import org.apache.syncope.core.provisioning.api.data.ClientAppDataBinder;
+import org.apache.syncope.core.provisioning.api.data.OIDCJWKSDataBinder;
+import org.apache.syncope.core.provisioning.api.data.SAML2IdPEntityDataBinder;
+import org.apache.syncope.core.provisioning.api.data.SAML2SPEntityDataBinder;
+import org.apache.syncope.core.provisioning.api.data.SRARouteDataBinder;
+import org.apache.syncope.core.provisioning.api.data.WAConfigDataBinder;
+import org.apache.syncope.core.provisioning.api.data.wa.WAClientAppDataBinder;
+import org.apache.syncope.core.spring.security.SecurityProperties;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class AMLogicContext {
+
+    @Autowired
+    private SecurityProperties securityProperties;
+
+    @Autowired
+    private ServiceOps serviceOps;
+
+    @Autowired
+    private AuthProfileDAO authProfileDAO;
+
+    @Autowired
+    private AuthProfileDataBinder authProfileDataBinder;
+
+    @Autowired
+    private CASSPDAO casspDAO;
+
+    @Autowired
+    private OIDCRPDAO oidcrpDAO;
+
+    @Autowired
+    private SAML2SPDAO saml2spDAO;
+
+    @Autowired
+    private EntityFactory entityFactory;
+
+    @ConditionalOnMissingBean
+    @Bean
+    public AMEntitlementLoader amEntitlementLoader() {
+        return new AMEntitlementLoader();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public AuthModuleLogic authModuleLogic(
+            final AuthModuleDataBinder binder,
+            final AuthModuleDAO authModuleDAO) {
+
+        return new AuthModuleLogic(binder, authModuleDAO);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public AuthProfileLogic authProfileLogic() {
+        return new AuthProfileLogic(authProfileDAO, authProfileDataBinder);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public ClientAppLogic clientAppLogic(
+            final ClientAppUtilsFactory clientAppUtilsFactory,
+            final ClientAppDataBinder binder) {
+
+        return new ClientAppLogic(
+                serviceOps,
+                clientAppUtilsFactory,
+                binder,
+                saml2spDAO,
+                oidcrpDAO,
+                casspDAO,
+                securityProperties);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public OIDCJWKSLogic oidcJWKSLogic(
+            final OIDCJWKSDataBinder binder,
+            final OIDCJWKSDAO dao) {
+
+        return new OIDCJWKSLogic(binder, dao);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public SAML2IdPEntityLogic saml2IdPEntityLogic(
+            final SAML2IdPEntityDataBinder binder,
+            final SAML2IdPEntityDAO entityDAO) {
+
+        return new SAML2IdPEntityLogic(binder, entityDAO);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public SAML2SPEntityLogic saml2SPEntityLogic(
+            final SAML2SPEntityDataBinder binder,
+            final SAML2SPEntityDAO entityDAO) {
+
+        return new SAML2SPEntityLogic(binder, entityDAO);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public SRARouteLogic sraRouteLogic(
+            final SRARouteDAO routeDAO,
+            final SRARouteDataBinder binder) {
+
+        return new SRARouteLogic(routeDAO, binder, entityFactory, serviceOps, securityProperties);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public GoogleMfaAuthAccountLogic googleMfaAuthAccountLogic() {
+        return new GoogleMfaAuthAccountLogic(entityFactory, authProfileDAO, authProfileDataBinder);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public GoogleMfaAuthTokenLogic googleMfaAuthTokenLogic() {
+        return new GoogleMfaAuthTokenLogic(entityFactory, authProfileDAO, authProfileDataBinder);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public ImpersonationLogic impersonationLogic() {
+        return new ImpersonationLogic(entityFactory, authProfileDAO, authProfileDataBinder);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public U2FRegistrationLogic u2fRegistrationLogic() {
+        return new U2FRegistrationLogic(entityFactory, authProfileDAO, authProfileDataBinder);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public WAClientAppLogic waClientAppLogic(final WAClientAppDataBinder binder) {
+        return new WAClientAppLogic(binder, saml2spDAO, oidcrpDAO, casspDAO);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public WAConfigLogic waConfigLogic(
+            final WAConfigDataBinder binder,
+            final WAConfigDAO waConfigDAO) {
+
+        return new WAConfigLogic(serviceOps, binder, waConfigDAO, securityProperties);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public WebAuthnRegistrationLogic webAuthnRegistrationLogic() {
+        return new WebAuthnRegistrationLogic(entityFactory, authProfileDAO, authProfileDataBinder);
+    }
+}
diff --git a/core/am/logic/src/main/java/org/apache/syncope/core/logic/AbstractAuthProfileLogic.java b/core/am/logic/src/main/java/org/apache/syncope/core/logic/AbstractAuthProfileLogic.java
index eaaba70..c81ddc7 100644
--- a/core/am/logic/src/main/java/org/apache/syncope/core/logic/AbstractAuthProfileLogic.java
+++ b/core/am/logic/src/main/java/org/apache/syncope/core/logic/AbstractAuthProfileLogic.java
@@ -23,15 +23,17 @@ import org.apache.commons.lang3.ArrayUtils;
 import org.apache.syncope.common.lib.to.AuthProfileTO;
 import org.apache.syncope.core.persistence.api.dao.auth.AuthProfileDAO;
 import org.apache.syncope.core.provisioning.api.data.AuthProfileDataBinder;
-import org.springframework.beans.factory.annotation.Autowired;
 
 public abstract class AbstractAuthProfileLogic extends AbstractTransactionalLogic<AuthProfileTO> {
 
-    @Autowired
-    protected AuthProfileDAO authProfileDAO;
+    protected final AuthProfileDAO authProfileDAO;
 
-    @Autowired
-    protected AuthProfileDataBinder binder;
+    protected final AuthProfileDataBinder binder;
+
+    public AbstractAuthProfileLogic(final AuthProfileDAO authProfileDAO, final AuthProfileDataBinder binder) {
+        this.authProfileDAO = authProfileDAO;
+        this.binder = binder;
+    }
 
     @Override
     protected AuthProfileTO resolveReference(final Method method, final Object... args)
diff --git a/core/am/logic/src/main/java/org/apache/syncope/core/logic/AuthModuleLogic.java b/core/am/logic/src/main/java/org/apache/syncope/core/logic/AuthModuleLogic.java
index 9cb29e8..3bc5b6c 100644
--- a/core/am/logic/src/main/java/org/apache/syncope/core/logic/AuthModuleLogic.java
+++ b/core/am/logic/src/main/java/org/apache/syncope/core/logic/AuthModuleLogic.java
@@ -29,19 +29,19 @@ import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.auth.AuthModuleDAO;
 import org.apache.syncope.core.persistence.api.entity.auth.AuthModule;
 import org.apache.syncope.core.provisioning.api.data.AuthModuleDataBinder;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class AuthModuleLogic extends AbstractTransactionalLogic<AuthModuleTO> {
 
-    @Autowired
-    private AuthModuleDataBinder binder;
+    protected final AuthModuleDataBinder binder;
 
-    @Autowired
-    private AuthModuleDAO authModuleDAO;
+    protected final AuthModuleDAO authModuleDAO;
+
+    public AuthModuleLogic(final AuthModuleDataBinder binder, final AuthModuleDAO authModuleDAO) {
+        this.binder = binder;
+        this.authModuleDAO = authModuleDAO;
+    }
 
     @PreAuthorize("hasRole('" + AMEntitlement.AUTH_MODULE_CREATE + "')")
     public AuthModuleTO create(final AuthModuleTO authModuleTO) {
diff --git a/core/am/logic/src/main/java/org/apache/syncope/core/logic/AuthProfileLogic.java b/core/am/logic/src/main/java/org/apache/syncope/core/logic/AuthProfileLogic.java
index 160a508..e572c16 100644
--- a/core/am/logic/src/main/java/org/apache/syncope/core/logic/AuthProfileLogic.java
+++ b/core/am/logic/src/main/java/org/apache/syncope/core/logic/AuthProfileLogic.java
@@ -25,14 +25,18 @@ import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.to.AuthProfileTO;
 import org.apache.syncope.common.lib.types.AMEntitlement;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.dao.auth.AuthProfileDAO;
 import org.apache.syncope.core.persistence.api.entity.auth.AuthProfile;
+import org.apache.syncope.core.provisioning.api.data.AuthProfileDataBinder;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class AuthProfileLogic extends AbstractAuthProfileLogic {
 
+    public AuthProfileLogic(final AuthProfileDAO authProfileDAO, final AuthProfileDataBinder binder) {
+        super(authProfileDAO, binder);
+    }
+
     @PreAuthorize("hasRole('" + AMEntitlement.AUTH_PROFILE_DELETE + "') ")
     public void delete(final String key) {
         authProfileDAO.delete(key);
diff --git a/core/am/logic/src/main/java/org/apache/syncope/core/logic/ClientAppLogic.java b/core/am/logic/src/main/java/org/apache/syncope/core/logic/ClientAppLogic.java
index ad4bf4b..6629fc0 100644
--- a/core/am/logic/src/main/java/org/apache/syncope/core/logic/ClientAppLogic.java
+++ b/core/am/logic/src/main/java/org/apache/syncope/core/logic/ClientAppLogic.java
@@ -48,38 +48,46 @@ import org.apache.syncope.core.persistence.api.entity.auth.ClientApp;
 import org.apache.syncope.core.persistence.api.entity.auth.ClientAppUtils;
 import org.apache.syncope.core.persistence.api.entity.auth.ClientAppUtilsFactory;
 import org.apache.syncope.core.provisioning.api.data.ClientAppDataBinder;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 import org.apache.syncope.core.persistence.api.entity.auth.SAML2SPClientApp;
 import org.apache.syncope.core.persistence.api.entity.auth.CASSPClientApp;
 import org.apache.syncope.core.persistence.api.entity.auth.OIDCRPClientApp;
 import org.apache.syncope.core.spring.security.SecurityProperties;
 
-@Component
 public class ClientAppLogic extends AbstractTransactionalLogic<ClientAppTO> {
 
-    @Autowired
-    private ServiceOps serviceOps;
+    protected final ServiceOps serviceOps;
 
-    @Autowired
-    private ClientAppUtilsFactory clientAppUtilsFactory;
+    protected final ClientAppUtilsFactory clientAppUtilsFactory;
 
-    @Autowired
-    private ClientAppDataBinder binder;
+    protected final ClientAppDataBinder binder;
 
-    @Autowired
-    private SAML2SPDAO saml2spDAO;
+    protected final SAML2SPDAO saml2spDAO;
 
-    @Autowired
-    private OIDCRPDAO oidcrpDAO;
+    protected final OIDCRPDAO oidcrpDAO;
 
-    @Autowired
-    private CASSPDAO casspDAO;
+    protected final CASSPDAO casspDAO;
 
-    @Autowired
-    private SecurityProperties securityProperties;
+    protected final SecurityProperties securityProperties;
+
+    public ClientAppLogic(
+            final ServiceOps serviceOps,
+            final ClientAppUtilsFactory clientAppUtilsFactory,
+            final ClientAppDataBinder binder,
+            final SAML2SPDAO saml2spDAO,
+            final OIDCRPDAO oidcrpDAO,
+            final CASSPDAO casspDAO,
+            final SecurityProperties securityProperties) {
+
+        this.serviceOps = serviceOps;
+        this.clientAppUtilsFactory = clientAppUtilsFactory;
+        this.binder = binder;
+        this.saml2spDAO = saml2spDAO;
+        this.oidcrpDAO = oidcrpDAO;
+        this.casspDAO = casspDAO;
+        this.securityProperties = securityProperties;
+    }
 
     @PreAuthorize("hasRole('" + AMEntitlement.CLIENTAPP_LIST + "')")
     public <T extends ClientAppTO> List<T> list(final ClientAppType type) {
@@ -100,7 +108,7 @@ public class ClientAppLogic extends AbstractTransactionalLogic<ClientAppTO> {
         return stream.collect(Collectors.toList());
     }
 
-    private static void checkType(final ClientAppType type, final ClientAppUtils clientAppUtils) {
+    protected void checkType(final ClientAppType type, final ClientAppUtils clientAppUtils) {
         if (clientAppUtils.getType() != type) {
             SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidRequest);
             sce.getElements().add("Found " + type + ", expected " + clientAppUtils.getType());
diff --git a/core/am/logic/src/main/java/org/apache/syncope/core/logic/OIDCJWKSLogic.java b/core/am/logic/src/main/java/org/apache/syncope/core/logic/OIDCJWKSLogic.java
index 8b2ab8c..0e03700 100644
--- a/core/am/logic/src/main/java/org/apache/syncope/core/logic/OIDCJWKSLogic.java
+++ b/core/am/logic/src/main/java/org/apache/syncope/core/logic/OIDCJWKSLogic.java
@@ -29,19 +29,19 @@ import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.auth.OIDCJWKSDAO;
 import org.apache.syncope.core.persistence.api.entity.auth.OIDCJWKS;
 import org.apache.syncope.core.provisioning.api.data.OIDCJWKSDataBinder;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class OIDCJWKSLogic extends AbstractTransactionalLogic<OIDCJWKSTO> {
 
-    @Autowired
-    private OIDCJWKSDataBinder binder;
+    protected final OIDCJWKSDataBinder binder;
 
-    @Autowired
-    private OIDCJWKSDAO dao;
+    protected final OIDCJWKSDAO dao;
+
+    public OIDCJWKSLogic(final OIDCJWKSDataBinder binder, final OIDCJWKSDAO dao) {
+        this.binder = binder;
+        this.dao = dao;
+    }
 
     @PreAuthorize("hasRole('" + AMEntitlement.OIDC_JWKS_READ + "') "
             + "or hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
diff --git a/core/am/logic/src/main/java/org/apache/syncope/core/logic/SAML2IdPEntityLogic.java b/core/am/logic/src/main/java/org/apache/syncope/core/logic/SAML2IdPEntityLogic.java
index bab3989..c8e7fe8 100644
--- a/core/am/logic/src/main/java/org/apache/syncope/core/logic/SAML2IdPEntityLogic.java
+++ b/core/am/logic/src/main/java/org/apache/syncope/core/logic/SAML2IdPEntityLogic.java
@@ -27,22 +27,22 @@ import org.apache.syncope.common.lib.to.SAML2IdPEntityTO;
 import org.apache.syncope.common.lib.types.AMEntitlement;
 import org.apache.syncope.common.lib.types.IdRepoEntitlement;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 import org.apache.syncope.core.persistence.api.entity.auth.SAML2IdPEntity;
 import org.apache.syncope.core.persistence.api.dao.auth.SAML2IdPEntityDAO;
 import org.apache.syncope.core.provisioning.api.data.SAML2IdPEntityDataBinder;
 
-@Component
 public class SAML2IdPEntityLogic extends AbstractTransactionalLogic<SAML2IdPEntityTO> {
 
-    @Autowired
-    private SAML2IdPEntityDataBinder binder;
+    protected final SAML2IdPEntityDataBinder binder;
 
-    @Autowired
-    private SAML2IdPEntityDAO entityDAO;
+    protected final SAML2IdPEntityDAO entityDAO;
+
+    public SAML2IdPEntityLogic(final SAML2IdPEntityDataBinder binder, final SAML2IdPEntityDAO entityDAO) {
+        this.binder = binder;
+        this.entityDAO = entityDAO;
+    }
 
     @PreAuthorize("hasRole('" + AMEntitlement.SAML2_IDP_ENTITY_LIST + "')")
     @Transactional(readOnly = true)
diff --git a/core/am/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPEntityLogic.java b/core/am/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPEntityLogic.java
index a3f5e81..2b8b898 100644
--- a/core/am/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPEntityLogic.java
+++ b/core/am/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPEntityLogic.java
@@ -30,19 +30,19 @@ import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.auth.SAML2SPEntityDAO;
 import org.apache.syncope.core.persistence.api.entity.auth.SAML2SPEntity;
 import org.apache.syncope.core.provisioning.api.data.SAML2SPEntityDataBinder;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class SAML2SPEntityLogic extends AbstractTransactionalLogic<SAML2SPEntityTO> {
 
-    @Autowired
-    private SAML2SPEntityDataBinder binder;
+    protected final SAML2SPEntityDataBinder binder;
 
-    @Autowired
-    private SAML2SPEntityDAO entityDAO;
+    protected final SAML2SPEntityDAO entityDAO;
+
+    public SAML2SPEntityLogic(final SAML2SPEntityDataBinder binder, final SAML2SPEntityDAO entityDAO) {
+        this.binder = binder;
+        this.entityDAO = entityDAO;
+    }
 
     @PreAuthorize("hasRole('" + AMEntitlement.SAML2_SP_ENTITY_LIST + "')")
     @Transactional(readOnly = true)
diff --git a/core/am/logic/src/main/java/org/apache/syncope/core/logic/SRARouteLogic.java b/core/am/logic/src/main/java/org/apache/syncope/core/logic/SRARouteLogic.java
index db4d326..5b1b23d 100644
--- a/core/am/logic/src/main/java/org/apache/syncope/core/logic/SRARouteLogic.java
+++ b/core/am/logic/src/main/java/org/apache/syncope/core/logic/SRARouteLogic.java
@@ -42,27 +42,33 @@ import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.SRARoute;
 import org.apache.syncope.core.provisioning.api.data.SRARouteDataBinder;
 import org.apache.syncope.core.spring.security.SecurityProperties;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 
-@Component
 public class SRARouteLogic extends AbstractTransactionalLogic<SRARouteTO> {
 
-    @Autowired
-    private SRARouteDAO routeDAO;
+    protected final SRARouteDAO routeDAO;
 
-    @Autowired
-    private SRARouteDataBinder binder;
+    protected final SRARouteDataBinder binder;
 
-    @Autowired
-    private EntityFactory entityFactory;
+    protected final EntityFactory entityFactory;
 
-    @Autowired
-    private ServiceOps serviceOps;
+    protected final ServiceOps serviceOps;
 
-    @Autowired
-    private SecurityProperties securityProperties;
+    protected final SecurityProperties securityProperties;
+
+    public SRARouteLogic(
+            final SRARouteDAO routeDAO,
+            final SRARouteDataBinder binder,
+            final EntityFactory entityFactory,
+            final ServiceOps serviceOps,
+            final SecurityProperties securityProperties) {
+
+        this.routeDAO = routeDAO;
+        this.binder = binder;
+        this.entityFactory = entityFactory;
+        this.serviceOps = serviceOps;
+        this.securityProperties = securityProperties;
+    }
 
     @PreAuthorize("isAuthenticated()")
     public List<SRARouteTO> list() {
diff --git a/core/am/logic/src/main/java/org/apache/syncope/core/logic/init/AMEntitlementLoader.java b/core/am/logic/src/main/java/org/apache/syncope/core/logic/init/AMEntitlementLoader.java
index 2ca422c..cef967d 100644
--- a/core/am/logic/src/main/java/org/apache/syncope/core/logic/init/AMEntitlementLoader.java
+++ b/core/am/logic/src/main/java/org/apache/syncope/core/logic/init/AMEntitlementLoader.java
@@ -21,9 +21,7 @@ package org.apache.syncope.core.logic.init;
 import org.apache.syncope.common.lib.types.EntitlementsHolder;
 import org.apache.syncope.common.lib.types.AMEntitlement;
 import org.apache.syncope.core.persistence.api.SyncopeCoreLoader;
-import org.springframework.stereotype.Component;
 
-@Component
 public class AMEntitlementLoader implements SyncopeCoreLoader {
 
     @Override
diff --git a/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/GoogleMfaAuthAccountLogic.java b/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/GoogleMfaAuthAccountLogic.java
index ecfe757..efcca61 100644
--- a/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/GoogleMfaAuthAccountLogic.java
+++ b/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/GoogleMfaAuthAccountLogic.java
@@ -25,18 +25,25 @@ import org.apache.syncope.common.lib.wa.GoogleMfaAuthAccount;
 import org.apache.syncope.common.lib.types.IdRepoEntitlement;
 import org.apache.syncope.core.logic.AbstractAuthProfileLogic;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.dao.auth.AuthProfileDAO;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.auth.AuthProfile;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.syncope.core.provisioning.api.data.AuthProfileDataBinder;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class GoogleMfaAuthAccountLogic extends AbstractAuthProfileLogic {
 
-    @Autowired
-    private EntityFactory entityFactory;
+    protected final EntityFactory entityFactory;
+
+    public GoogleMfaAuthAccountLogic(
+            final EntityFactory entityFactory,
+            final AuthProfileDAO authProfileDAO,
+            final AuthProfileDataBinder binder) {
+
+        super(authProfileDAO, binder);
+        this.entityFactory = entityFactory;
+    }
 
     @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
     @Transactional(readOnly = true)
@@ -60,21 +67,21 @@ public class GoogleMfaAuthAccountLogic extends AbstractAuthProfileLogic {
     @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
     public void delete(final long id) {
         authProfileDAO.findAll(-1, -1).
-            stream().
-            filter(Objects::nonNull).
-            filter(profile -> profile.
+                stream().
+                filter(Objects::nonNull).
+                filter(profile -> profile.
                 getGoogleMfaAuthAccounts().
                 stream().
                 allMatch(acct -> acct.getId() == id)).
-            findFirst().
-            ifPresentOrElse(profile -> {
-                if (profile.getGoogleMfaAuthAccounts().removeIf(acct -> acct.getId() == id)) {
-                    authProfileDAO.save(profile);
-                }
-            },
-            () -> {
-                throw new NotFoundException("Could not find account for id " + id);
-            });
+                findFirst().
+                ifPresentOrElse(profile -> {
+                    if (profile.getGoogleMfaAuthAccounts().removeIf(acct -> acct.getId() == id)) {
+                        authProfileDAO.save(profile);
+                    }
+                },
+                        () -> {
+                            throw new NotFoundException("Could not find account for id " + id);
+                        });
     }
 
     @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
diff --git a/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/GoogleMfaAuthTokenLogic.java b/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/GoogleMfaAuthTokenLogic.java
index b5d445b..e83d1bc 100644
--- a/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/GoogleMfaAuthTokenLogic.java
+++ b/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/GoogleMfaAuthTokenLogic.java
@@ -26,18 +26,25 @@ import org.apache.syncope.common.lib.wa.GoogleMfaAuthToken;
 import org.apache.syncope.common.lib.types.IdRepoEntitlement;
 import org.apache.syncope.core.logic.AbstractAuthProfileLogic;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.dao.auth.AuthProfileDAO;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.auth.AuthProfile;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.syncope.core.provisioning.api.data.AuthProfileDataBinder;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class GoogleMfaAuthTokenLogic extends AbstractAuthProfileLogic {
 
-    @Autowired
-    private EntityFactory entityFactory;
+    protected final EntityFactory entityFactory;
+
+    public GoogleMfaAuthTokenLogic(
+            final EntityFactory entityFactory,
+            final AuthProfileDAO authProfileDAO,
+            final AuthProfileDataBinder binder) {
+
+        super(authProfileDAO, binder);
+        this.entityFactory = entityFactory;
+    }
 
     @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
     public void delete(final Date expirationDate) {
diff --git a/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/ImpersonationLogic.java b/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/ImpersonationLogic.java
index f1fd730..a9675b6 100644
--- a/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/ImpersonationLogic.java
+++ b/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/ImpersonationLogic.java
@@ -23,18 +23,25 @@ import java.util.List;
 import org.apache.syncope.common.lib.types.IdRepoEntitlement;
 import org.apache.syncope.common.lib.wa.ImpersonationAccount;
 import org.apache.syncope.core.logic.AbstractAuthProfileLogic;
+import org.apache.syncope.core.persistence.api.dao.auth.AuthProfileDAO;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.auth.AuthProfile;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.syncope.core.provisioning.api.data.AuthProfileDataBinder;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class ImpersonationLogic extends AbstractAuthProfileLogic {
 
-    @Autowired
-    private EntityFactory entityFactory;
+    protected final EntityFactory entityFactory;
+
+    public ImpersonationLogic(
+            final EntityFactory entityFactory,
+            final AuthProfileDAO authProfileDAO,
+            final AuthProfileDataBinder binder) {
+
+        super(authProfileDAO, binder);
+        this.entityFactory = entityFactory;
+    }
 
     @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
     @Transactional(readOnly = true)
diff --git a/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/U2FRegistrationLogic.java b/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/U2FRegistrationLogic.java
index e850e74..c32787a 100644
--- a/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/U2FRegistrationLogic.java
+++ b/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/U2FRegistrationLogic.java
@@ -29,18 +29,25 @@ import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.types.IdRepoEntitlement;
 import org.apache.syncope.common.lib.wa.U2FDevice;
 import org.apache.syncope.core.logic.AbstractAuthProfileLogic;
+import org.apache.syncope.core.persistence.api.dao.auth.AuthProfileDAO;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.auth.AuthProfile;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.syncope.core.provisioning.api.data.AuthProfileDataBinder;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 
-@Component
 public class U2FRegistrationLogic extends AbstractAuthProfileLogic {
 
-    @Autowired
-    private EntityFactory entityFactory;
+    protected final EntityFactory entityFactory;
+
+    public U2FRegistrationLogic(
+            final EntityFactory entityFactory,
+            final AuthProfileDAO authProfileDAO,
+            final AuthProfileDataBinder binder) {
+
+        super(authProfileDAO, binder);
+        this.entityFactory = entityFactory;
+    }
 
     @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
     public void create(final String owner, final U2FDevice device) {
diff --git a/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/WAClientAppLogic.java b/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/WAClientAppLogic.java
index 64c8d76..3fc07d0 100644
--- a/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/WAClientAppLogic.java
+++ b/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/WAClientAppLogic.java
@@ -29,29 +29,34 @@ import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.auth.CASSPDAO;
 import org.apache.syncope.core.persistence.api.dao.auth.OIDCRPDAO;
 import org.apache.syncope.core.persistence.api.dao.auth.SAML2SPDAO;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 import org.apache.syncope.core.provisioning.api.data.wa.WAClientAppDataBinder;
 import org.apache.syncope.core.persistence.api.entity.auth.SAML2SPClientApp;
 import org.apache.syncope.core.persistence.api.entity.auth.CASSPClientApp;
 import org.apache.syncope.core.persistence.api.entity.auth.OIDCRPClientApp;
 
-@Component
 public class WAClientAppLogic {
 
-    @Autowired
-    private WAClientAppDataBinder binder;
+    protected final WAClientAppDataBinder binder;
 
-    @Autowired
-    private SAML2SPDAO saml2spDAO;
+    protected final SAML2SPDAO saml2spDAO;
 
-    @Autowired
-    private OIDCRPDAO oidcrpDAO;
+    protected final OIDCRPDAO oidcrpDAO;
 
-    @Autowired
-    private CASSPDAO casspDAO;
+    protected final CASSPDAO casspDAO;
+
+    public WAClientAppLogic(
+            final WAClientAppDataBinder binder,
+            final SAML2SPDAO saml2spDAO,
+            final OIDCRPDAO oidcrpDAO,
+            final CASSPDAO casspDAO) {
+
+        this.binder = binder;
+        this.saml2spDAO = saml2spDAO;
+        this.oidcrpDAO = oidcrpDAO;
+        this.casspDAO = casspDAO;
+    }
 
     @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
     @Transactional(readOnly = true)
@@ -80,7 +85,7 @@ public class WAClientAppLogic {
         return clientApps;
     }
 
-    private WAClientApp doRead(final Long clientAppId, final ClientAppType type) {
+    protected WAClientApp doRead(final Long clientAppId, final ClientAppType type) {
         WAClientApp clientApp = null;
 
         switch (type) {
@@ -130,7 +135,7 @@ public class WAClientAppLogic {
         return clientApp;
     }
 
-    private WAClientApp doRead(final String name, final ClientAppType type) {
+    protected WAClientApp doRead(final String name, final ClientAppType type) {
         WAClientApp clientApp = null;
 
         switch (type) {
diff --git a/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/WAConfigLogic.java b/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/WAConfigLogic.java
index b02b3dd..cb103f3 100644
--- a/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/WAConfigLogic.java
+++ b/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/WAConfigLogic.java
@@ -44,25 +44,30 @@ import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.auth.WAConfigDAO;
 import org.apache.syncope.core.provisioning.api.data.WAConfigDataBinder;
 import org.apache.syncope.core.spring.security.SecurityProperties;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class WAConfigLogic extends AbstractTransactionalLogic<EntityTO> {
 
-    @Autowired
-    private ServiceOps serviceOps;
+    protected final ServiceOps serviceOps;
 
-    @Autowired
-    private WAConfigDataBinder binder;
+    protected final WAConfigDataBinder binder;
 
-    @Autowired
-    private WAConfigDAO waConfigDAO;
+    protected final WAConfigDAO waConfigDAO;
 
-    @Autowired
-    private SecurityProperties securityProperties;
+    protected final SecurityProperties securityProperties;
+
+    public WAConfigLogic(
+            final ServiceOps serviceOps,
+            final WAConfigDataBinder binder,
+            final WAConfigDAO waConfigDAO,
+            final SecurityProperties securityProperties) {
+
+        this.serviceOps = serviceOps;
+        this.binder = binder;
+        this.waConfigDAO = waConfigDAO;
+        this.securityProperties = securityProperties;
+    }
 
     @PreAuthorize("hasRole('" + AMEntitlement.WA_CONFIG_LIST + "') or hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
     @Transactional(readOnly = true)
diff --git a/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/WebAuthnRegistrationLogic.java b/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/WebAuthnRegistrationLogic.java
index 27b6aa0..e9cb9c6 100644
--- a/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/WebAuthnRegistrationLogic.java
+++ b/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/WebAuthnRegistrationLogic.java
@@ -25,18 +25,25 @@ import org.apache.syncope.common.lib.wa.WebAuthnAccount;
 import org.apache.syncope.common.lib.wa.WebAuthnDeviceCredential;
 import org.apache.syncope.core.logic.AbstractAuthProfileLogic;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.dao.auth.AuthProfileDAO;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.auth.AuthProfile;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.syncope.core.provisioning.api.data.AuthProfileDataBinder;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class WebAuthnRegistrationLogic extends AbstractAuthProfileLogic {
 
-    @Autowired
-    private EntityFactory entityFactory;
+    protected final EntityFactory entityFactory;
+
+    public WebAuthnRegistrationLogic(
+            final EntityFactory entityFactory,
+            final AuthProfileDAO authProfileDAO,
+            final AuthProfileDataBinder binder) {
+
+        super(authProfileDAO, binder);
+        this.entityFactory = entityFactory;
+    }
 
     @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
     @Transactional(readOnly = true)
diff --git a/core/idrepo/logic/src/main/resources/META-INF/spring.factories b/core/am/logic/src/main/resources/META-INF/spring.factories
similarity index 94%
copy from core/idrepo/logic/src/main/resources/META-INF/spring.factories
copy to core/am/logic/src/main/resources/META-INF/spring.factories
index eb5b93f..e014d8c 100644
--- a/core/idrepo/logic/src/main/resources/META-INF/spring.factories
+++ b/core/am/logic/src/main/resources/META-INF/spring.factories
@@ -16,4 +16,4 @@
 # under the License.
 
 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-  org.apache.syncope.core.logic.LogicContext
+  org.apache.syncope.core.logic.AMLogicContext
diff --git a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/AMRESTCXFContext.java b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/AMRESTCXFContext.java
new file mode 100644
index 0000000..913865c
--- /dev/null
+++ b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/AMRESTCXFContext.java
@@ -0,0 +1,174 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.rest.cxf;
+
+import org.apache.syncope.common.rest.api.service.AuthModuleService;
+import org.apache.syncope.common.rest.api.service.AuthProfileService;
+import org.apache.syncope.common.rest.api.service.ClientAppService;
+import org.apache.syncope.common.rest.api.service.OIDCJWKSService;
+import org.apache.syncope.common.rest.api.service.SAML2IdPEntityService;
+import org.apache.syncope.common.rest.api.service.SAML2SPEntityService;
+import org.apache.syncope.common.rest.api.service.SRARouteService;
+import org.apache.syncope.common.rest.api.service.wa.GoogleMfaAuthAccountService;
+import org.apache.syncope.common.rest.api.service.wa.GoogleMfaAuthTokenService;
+import org.apache.syncope.common.rest.api.service.wa.ImpersonationService;
+import org.apache.syncope.common.rest.api.service.wa.U2FRegistrationService;
+import org.apache.syncope.common.rest.api.service.wa.WAClientAppService;
+import org.apache.syncope.common.rest.api.service.wa.WAConfigService;
+import org.apache.syncope.common.rest.api.service.wa.WebAuthnRegistrationService;
+import org.apache.syncope.core.logic.AuthModuleLogic;
+import org.apache.syncope.core.logic.AuthProfileLogic;
+import org.apache.syncope.core.logic.ClientAppLogic;
+import org.apache.syncope.core.logic.OIDCJWKSLogic;
+import org.apache.syncope.core.logic.SAML2IdPEntityLogic;
+import org.apache.syncope.core.logic.SAML2SPEntityLogic;
+import org.apache.syncope.core.logic.SRARouteLogic;
+import org.apache.syncope.core.logic.wa.GoogleMfaAuthAccountLogic;
+import org.apache.syncope.core.logic.wa.GoogleMfaAuthTokenLogic;
+import org.apache.syncope.core.logic.wa.ImpersonationLogic;
+import org.apache.syncope.core.logic.wa.U2FRegistrationLogic;
+import org.apache.syncope.core.logic.wa.WAClientAppLogic;
+import org.apache.syncope.core.logic.wa.WAConfigLogic;
+import org.apache.syncope.core.logic.wa.WebAuthnRegistrationLogic;
+import org.apache.syncope.core.rest.cxf.service.AuthModuleServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.AuthProfileServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.ClientAppServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.OIDCJWKSServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.SAML2IdPEntityServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.SAML2SPEntityServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.SRARouteServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.wa.GoogleMfaAuthAccountServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.wa.GoogleMfaAuthTokenServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.wa.ImpersonationServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.wa.U2FRegistrationServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.wa.WAClientAppServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.wa.WAConfigServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.wa.WebAuthnRegistrationServiceImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class AMRESTCXFContext {
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public AuthModuleService authModuleService(final AuthModuleLogic authModuleLogic) {
+        return new AuthModuleServiceImpl(authModuleLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public AuthProfileService authProfileService(final AuthProfileLogic authProfileLogic) {
+        return new AuthProfileServiceImpl(authProfileLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public ClientAppService clientAppService(final ClientAppLogic clientAppLogic) {
+        return new ClientAppServiceImpl(clientAppLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public GoogleMfaAuthAccountService googleMfaAuthAccountService(
+            final GoogleMfaAuthAccountLogic googleMfaAuthAccountLogic) {
+
+        return new GoogleMfaAuthAccountServiceImpl(googleMfaAuthAccountLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public GoogleMfaAuthTokenService googleMfaAuthTokenService(
+            final GoogleMfaAuthTokenLogic googleMfaAuthTokenLogic) {
+
+        return new GoogleMfaAuthTokenServiceImpl(googleMfaAuthTokenLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public ImpersonationService impersonationService(final ImpersonationLogic impersonationLogic) {
+        return new ImpersonationServiceImpl(impersonationLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public OIDCJWKSService oidcJWKSService(final OIDCJWKSLogic oidcJWKSLogic) {
+        return new OIDCJWKSServiceImpl(oidcJWKSLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public SAML2IdPEntityService saml2IdPEntityService(final SAML2IdPEntityLogic saml2IdPEntityLogic) {
+        return new SAML2IdPEntityServiceImpl(saml2IdPEntityLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public SAML2SPEntityService saml2SPEntityService(final SAML2SPEntityLogic saml2SPEntityLogic) {
+        return new SAML2SPEntityServiceImpl(saml2SPEntityLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public SRARouteService sraRouteService(final SRARouteLogic sraRouteLogic) {
+        return new SRARouteServiceImpl(sraRouteLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public U2FRegistrationService u2fRegistrationService(final U2FRegistrationLogic u2fRegistrationLogic) {
+        return new U2FRegistrationServiceImpl(u2fRegistrationLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public WAClientAppService waClientAppService(final WAClientAppLogic waClientAppLogic) {
+        return new WAClientAppServiceImpl(waClientAppLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public WAConfigService waConfigService(final WAConfigLogic waConfigLogic) {
+        return new WAConfigServiceImpl(waConfigLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public WebAuthnRegistrationService webAuthnRegistrationService(
+            final WebAuthnRegistrationLogic webAuthnRegistrationLogic) {
+
+        return new WebAuthnRegistrationServiceImpl(webAuthnRegistrationLogic);
+    }
+}
diff --git a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AuthModuleServiceImpl.java b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AuthModuleServiceImpl.java
index 68bdd90..f5ba667 100644
--- a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AuthModuleServiceImpl.java
+++ b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AuthModuleServiceImpl.java
@@ -25,14 +25,16 @@ import org.apache.syncope.common.lib.to.AuthModuleTO;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.AuthModuleService;
 import org.apache.syncope.core.logic.AuthModuleLogic;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
-public class AuthModuleServiceImpl extends AbstractServiceImpl implements AuthModuleService {
+public class AuthModuleServiceImpl extends AbstractService implements AuthModuleService {
 
-    @Autowired
-    private AuthModuleLogic logic;
+    protected final AuthModuleLogic logic;
+
+    public AuthModuleServiceImpl(final AuthModuleLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public Response create(final AuthModuleTO authModuleTO) {
diff --git a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AuthProfileServiceImpl.java b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AuthProfileServiceImpl.java
index 3ee15a9..48efd31 100644
--- a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AuthProfileServiceImpl.java
+++ b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AuthProfileServiceImpl.java
@@ -22,7 +22,6 @@ import java.net.URI;
 import org.apache.syncope.common.lib.to.AuthProfileTO;
 import org.apache.syncope.common.rest.api.service.AuthProfileService;
 import org.apache.syncope.core.logic.AuthProfileLogic;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.util.List;
@@ -32,10 +31,13 @@ import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 
 @Service
-public class AuthProfileServiceImpl extends AbstractServiceImpl implements AuthProfileService {
+public class AuthProfileServiceImpl extends AbstractService implements AuthProfileService {
 
-    @Autowired
-    private AuthProfileLogic logic;
+    protected final AuthProfileLogic logic;
+
+    public AuthProfileServiceImpl(final AuthProfileLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public void delete(final String key) {
diff --git a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ClientAppServiceImpl.java b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ClientAppServiceImpl.java
index 5a2c462..da1e1e0 100644
--- a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ClientAppServiceImpl.java
+++ b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ClientAppServiceImpl.java
@@ -26,14 +26,16 @@ import org.apache.syncope.common.lib.types.ClientAppType;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.ClientAppService;
 import org.apache.syncope.core.logic.ClientAppLogic;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
-public class ClientAppServiceImpl extends AbstractServiceImpl implements ClientAppService {
+public class ClientAppServiceImpl extends AbstractService implements ClientAppService {
 
-    @Autowired
-    private ClientAppLogic logic;
+    protected final ClientAppLogic logic;
+
+    public ClientAppServiceImpl(final ClientAppLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public Response create(final ClientAppType type, final ClientAppTO clientAppTO) {
diff --git a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/OIDCJWKSServiceImpl.java b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/OIDCJWKSServiceImpl.java
index 67c1b82..a4fcb71 100644
--- a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/OIDCJWKSServiceImpl.java
+++ b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/OIDCJWKSServiceImpl.java
@@ -23,15 +23,17 @@ import javax.ws.rs.core.Response;
 import org.apache.syncope.common.lib.to.OIDCJWKSTO;
 import org.apache.syncope.common.lib.types.JWSAlgorithm;
 import org.apache.syncope.core.logic.OIDCJWKSLogic;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.apache.syncope.common.rest.api.service.OIDCJWKSService;
 
 @Service
-public class OIDCJWKSServiceImpl extends AbstractServiceImpl implements OIDCJWKSService {
+public class OIDCJWKSServiceImpl extends AbstractService implements OIDCJWKSService {
 
-    @Autowired
-    private OIDCJWKSLogic logic;
+    protected final OIDCJWKSLogic logic;
+
+    public OIDCJWKSServiceImpl(final OIDCJWKSLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public OIDCJWKSTO get() {
diff --git a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2IdPEntityServiceImpl.java b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2IdPEntityServiceImpl.java
index 6fe5bb7..8edc01d 100644
--- a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2IdPEntityServiceImpl.java
+++ b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2IdPEntityServiceImpl.java
@@ -21,15 +21,17 @@ package org.apache.syncope.core.rest.cxf.service;
 import java.util.List;
 import org.apache.syncope.common.lib.to.SAML2IdPEntityTO;
 import org.apache.syncope.core.logic.SAML2IdPEntityLogic;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.apache.syncope.common.rest.api.service.SAML2IdPEntityService;
 
 @Service
-public class SAML2IdPEntityServiceImpl extends AbstractServiceImpl implements SAML2IdPEntityService {
+public class SAML2IdPEntityServiceImpl extends AbstractService implements SAML2IdPEntityService {
 
-    @Autowired
-    private SAML2IdPEntityLogic logic;
+    protected final SAML2IdPEntityLogic logic;
+
+    public SAML2IdPEntityServiceImpl(final SAML2IdPEntityLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public List<SAML2IdPEntityTO> list() {
diff --git a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2SPEntityServiceImpl.java b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2SPEntityServiceImpl.java
index 94217d2..53f01ae 100644
--- a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2SPEntityServiceImpl.java
+++ b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2SPEntityServiceImpl.java
@@ -21,15 +21,17 @@ package org.apache.syncope.core.rest.cxf.service;
 import java.util.List;
 import org.apache.syncope.common.lib.to.SAML2SPEntityTO;
 import org.apache.syncope.core.logic.SAML2SPEntityLogic;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.apache.syncope.common.rest.api.service.SAML2SPEntityService;
 
 @Service
-public class SAML2SPEntityServiceImpl extends AbstractServiceImpl implements SAML2SPEntityService {
+public class SAML2SPEntityServiceImpl extends AbstractService implements SAML2SPEntityService {
 
-    @Autowired
-    private SAML2SPEntityLogic logic;
+    protected final SAML2SPEntityLogic logic;
+
+    public SAML2SPEntityServiceImpl(final SAML2SPEntityLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public List<SAML2SPEntityTO> list() {
diff --git a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SRARouteServiceImpl.java b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SRARouteServiceImpl.java
index 8bbda31..8eb26c3 100644
--- a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SRARouteServiceImpl.java
+++ b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SRARouteServiceImpl.java
@@ -25,14 +25,16 @@ import org.apache.syncope.common.lib.to.SRARouteTO;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.SRARouteService;
 import org.apache.syncope.core.logic.SRARouteLogic;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
-public class SRARouteServiceImpl extends AbstractServiceImpl implements SRARouteService {
+public class SRARouteServiceImpl extends AbstractService implements SRARouteService {
 
-    @Autowired
-    private SRARouteLogic logic;
+    protected final SRARouteLogic logic;
+
+    public SRARouteServiceImpl(final SRARouteLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public List<SRARouteTO> list() {
diff --git a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/GoogleMfaAuthAccountServiceImpl.java b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/GoogleMfaAuthAccountServiceImpl.java
index 658298a..2c8d95b 100644
--- a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/GoogleMfaAuthAccountServiceImpl.java
+++ b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/GoogleMfaAuthAccountServiceImpl.java
@@ -23,15 +23,17 @@ import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.wa.GoogleMfaAuthAccount;
 import org.apache.syncope.common.rest.api.service.wa.GoogleMfaAuthAccountService;
 import org.apache.syncope.core.logic.wa.GoogleMfaAuthAccountLogic;
-import org.apache.syncope.core.rest.cxf.service.AbstractServiceImpl;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.syncope.core.rest.cxf.service.AbstractService;
 import org.springframework.stereotype.Service;
 
 @Service
-public class GoogleMfaAuthAccountServiceImpl extends AbstractServiceImpl implements GoogleMfaAuthAccountService {
+public class GoogleMfaAuthAccountServiceImpl extends AbstractService implements GoogleMfaAuthAccountService {
 
-    @Autowired
-    private GoogleMfaAuthAccountLogic logic;
+    protected final GoogleMfaAuthAccountLogic logic;
+
+    public GoogleMfaAuthAccountServiceImpl(final GoogleMfaAuthAccountLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public void delete(final String owner) {
diff --git a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/GoogleMfaAuthTokenServiceImpl.java b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/GoogleMfaAuthTokenServiceImpl.java
index f4ce58d..b3b328d 100644
--- a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/GoogleMfaAuthTokenServiceImpl.java
+++ b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/GoogleMfaAuthTokenServiceImpl.java
@@ -24,15 +24,17 @@ import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.wa.GoogleMfaAuthToken;
 import org.apache.syncope.common.rest.api.service.wa.GoogleMfaAuthTokenService;
 import org.apache.syncope.core.logic.wa.GoogleMfaAuthTokenLogic;
-import org.apache.syncope.core.rest.cxf.service.AbstractServiceImpl;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.syncope.core.rest.cxf.service.AbstractService;
 import org.springframework.stereotype.Service;
 
 @Service
-public class GoogleMfaAuthTokenServiceImpl extends AbstractServiceImpl implements GoogleMfaAuthTokenService {
+public class GoogleMfaAuthTokenServiceImpl extends AbstractService implements GoogleMfaAuthTokenService {
 
-    @Autowired
-    private GoogleMfaAuthTokenLogic logic;
+    protected final GoogleMfaAuthTokenLogic logic;
+
+    public GoogleMfaAuthTokenServiceImpl(final GoogleMfaAuthTokenLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public void delete(final Date expirationDate) {
diff --git a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/ImpersonationServiceImpl.java b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/ImpersonationServiceImpl.java
index 2feb8b8..94b648e 100644
--- a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/ImpersonationServiceImpl.java
+++ b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/ImpersonationServiceImpl.java
@@ -22,15 +22,17 @@ import java.util.List;
 import org.apache.syncope.common.lib.wa.ImpersonationAccount;
 import org.apache.syncope.common.rest.api.service.wa.ImpersonationService;
 import org.apache.syncope.core.logic.wa.ImpersonationLogic;
-import org.apache.syncope.core.rest.cxf.service.AbstractServiceImpl;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.syncope.core.rest.cxf.service.AbstractService;
 import org.springframework.stereotype.Service;
 
 @Service
-public class ImpersonationServiceImpl extends AbstractServiceImpl implements ImpersonationService {
+public class ImpersonationServiceImpl extends AbstractService implements ImpersonationService {
 
-    @Autowired
-    private ImpersonationLogic logic;
+    protected final ImpersonationLogic logic;
+
+    public ImpersonationServiceImpl(final ImpersonationLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public List<ImpersonationAccount> read(final String owner) {
diff --git a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/U2FRegistrationServiceImpl.java b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/U2FRegistrationServiceImpl.java
index 0a5d596..7e836e0 100644
--- a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/U2FRegistrationServiceImpl.java
+++ b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/U2FRegistrationServiceImpl.java
@@ -25,15 +25,17 @@ import org.apache.syncope.common.lib.wa.U2FDevice;
 import org.apache.syncope.common.rest.api.beans.U2FDeviceQuery;
 import org.apache.syncope.common.rest.api.service.wa.U2FRegistrationService;
 import org.apache.syncope.core.logic.wa.U2FRegistrationLogic;
-import org.apache.syncope.core.rest.cxf.service.AbstractServiceImpl;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.syncope.core.rest.cxf.service.AbstractService;
 import org.springframework.stereotype.Service;
 
 @Service
-public class U2FRegistrationServiceImpl extends AbstractServiceImpl implements U2FRegistrationService {
+public class U2FRegistrationServiceImpl extends AbstractService implements U2FRegistrationService {
 
-    @Autowired
-    private U2FRegistrationLogic logic;
+    protected final U2FRegistrationLogic logic;
+
+    public U2FRegistrationServiceImpl(final U2FRegistrationLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public void delete(final U2FDeviceQuery query) {
diff --git a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/WAClientAppServiceImpl.java b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/WAClientAppServiceImpl.java
index fcd9061..34dc4d8 100644
--- a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/WAClientAppServiceImpl.java
+++ b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/WAClientAppServiceImpl.java
@@ -23,15 +23,17 @@ import org.apache.syncope.common.lib.types.ClientAppType;
 import org.apache.syncope.common.lib.wa.WAClientApp;
 import org.apache.syncope.common.rest.api.service.wa.WAClientAppService;
 import org.apache.syncope.core.logic.wa.WAClientAppLogic;
-import org.apache.syncope.core.rest.cxf.service.AbstractServiceImpl;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.syncope.core.rest.cxf.service.AbstractService;
 import org.springframework.stereotype.Service;
 
 @Service
-public class WAClientAppServiceImpl extends AbstractServiceImpl implements WAClientAppService {
+public class WAClientAppServiceImpl extends AbstractService implements WAClientAppService {
 
-    @Autowired
-    private WAClientAppLogic logic;
+    protected final WAClientAppLogic logic;
+
+    public WAClientAppServiceImpl(final WAClientAppLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public List<WAClientApp> list() {
diff --git a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/WAConfigServiceImpl.java b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/WAConfigServiceImpl.java
index 81d5303..8940377 100644
--- a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/WAConfigServiceImpl.java
+++ b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/WAConfigServiceImpl.java
@@ -21,16 +21,18 @@ package org.apache.syncope.core.rest.cxf.service.wa;
 import java.util.List;
 import org.apache.syncope.common.lib.Attr;
 import org.apache.syncope.common.rest.api.service.wa.WAConfigService;
-import org.apache.syncope.core.rest.cxf.service.AbstractServiceImpl;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.apache.syncope.core.logic.wa.WAConfigLogic;
+import org.apache.syncope.core.rest.cxf.service.AbstractService;
 
 @Service
-public class WAConfigServiceImpl extends AbstractServiceImpl implements WAConfigService {
+public class WAConfigServiceImpl extends AbstractService implements WAConfigService {
 
-    @Autowired
-    private WAConfigLogic logic;
+    protected final WAConfigLogic logic;
+
+    public WAConfigServiceImpl(final WAConfigLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public List<Attr> list() {
diff --git a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/WebAuthnRegistrationServiceImpl.java b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/WebAuthnRegistrationServiceImpl.java
index 91105f2..aa31b0d 100644
--- a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/WebAuthnRegistrationServiceImpl.java
+++ b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/WebAuthnRegistrationServiceImpl.java
@@ -22,15 +22,17 @@ import java.util.List;
 import org.apache.syncope.common.lib.wa.WebAuthnAccount;
 import org.apache.syncope.common.rest.api.service.wa.WebAuthnRegistrationService;
 import org.apache.syncope.core.logic.wa.WebAuthnRegistrationLogic;
-import org.apache.syncope.core.rest.cxf.service.AbstractServiceImpl;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.syncope.core.rest.cxf.service.AbstractService;
 import org.springframework.stereotype.Service;
 
 @Service
-public class WebAuthnRegistrationServiceImpl extends AbstractServiceImpl implements WebAuthnRegistrationService {
+public class WebAuthnRegistrationServiceImpl extends AbstractService implements WebAuthnRegistrationService {
 
-    @Autowired
-    private WebAuthnRegistrationLogic logic;
+    protected final WebAuthnRegistrationLogic logic;
+
+    public WebAuthnRegistrationServiceImpl(final WebAuthnRegistrationLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public List<WebAuthnAccount> list() {
diff --git a/ext/saml2sp4ui/logic/src/main/resources/META-INF/spring.factories b/core/am/rest-cxf/src/main/resources/META-INF/spring.factories
similarity index 94%
copy from ext/saml2sp4ui/logic/src/main/resources/META-INF/spring.factories
copy to core/am/rest-cxf/src/main/resources/META-INF/spring.factories
index 6cb5b1c..190e531 100644
--- a/ext/saml2sp4ui/logic/src/main/resources/META-INF/spring.factories
+++ b/core/am/rest-cxf/src/main/resources/META-INF/spring.factories
@@ -16,4 +16,4 @@
 # under the License.
 
 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-  org.apache.syncope.core.logic.SAML2SP4UIContext
+  org.apache.syncope.core.rest.cxf.AMRESTCXFContext
diff --git a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java
index a3c5d53..a4606fb 100644
--- a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java
+++ b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java
@@ -42,7 +42,7 @@ import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
-import org.apache.syncope.core.provisioning.api.ConnectorFactory;
+import org.apache.syncope.core.provisioning.api.ConnectorManager;
 import org.apache.syncope.core.provisioning.api.data.ConnInstanceDataBinder;
 import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
@@ -52,36 +52,54 @@ import org.identityconnectors.framework.api.ConfigurationProperties;
 import org.identityconnectors.framework.api.ConnectorKey;
 import org.identityconnectors.framework.common.objects.AttributeUtil;
 import org.identityconnectors.framework.common.objects.ObjectClassInfo;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class ConnectorLogic extends AbstractTransactionalLogic<ConnInstanceTO> {
 
-    @Autowired
-    private ConnIdBundleManager connIdBundleManager;
+    protected final ConnIdBundleManager connIdBundleManager;
 
-    @Autowired
-    private ExternalResourceDAO resourceDAO;
+    protected final ConnectorManager connectorManager;
 
-    @Autowired
-    private ConnInstanceDAO connInstanceDAO;
+    protected final ExternalResourceDAO resourceDAO;
 
-    @Autowired
-    private ConnInstanceDataBinder binder;
+    protected final ConnInstanceDAO connInstanceDAO;
 
-    @Autowired
-    private ConnectorFactory connFactory;
+    protected final ConnInstanceDataBinder binder;
 
-    protected static void securityChecks(final Set<String> effectiveRealms, final String realm, final String key) {
+    public ConnectorLogic(
+            final ConnIdBundleManager connIdBundleManager,
+            final ConnectorManager connectorManager,
+            final ExternalResourceDAO resourceDAO,
+            final ConnInstanceDAO connInstanceDAO,
+            final ConnInstanceDataBinder binder) {
+
+        this.connIdBundleManager = connIdBundleManager;
+        this.connectorManager = connectorManager;
+        this.resourceDAO = resourceDAO;
+        this.connInstanceDAO = connInstanceDAO;
+        this.binder = binder;
+    }
+
+    protected void securityChecks(final Set<String> effectiveRealms, final String realm, final String key) {
         boolean authorized = effectiveRealms.stream().anyMatch(realm::startsWith);
         if (!authorized) {
             throw new DelegatedAdministrationException(realm, ConnInstance.class.getSimpleName(), key);
         }
     }
 
+    protected ConnInstance doSave(final ConnInstance connInstance) {
+        ConnInstance merged = connInstanceDAO.save(connInstance);
+        merged.getResources().forEach(resource -> {
+            try {
+                connectorManager.registerConnector(resource);
+            } catch (NotFoundException e) {
+                LOG.error("While registering connector {} for resource {}", merged, resource, e);
+            }
+        });
+        return merged;
+    }
+
     @PreAuthorize("hasRole('" + IdMEntitlement.CONNECTOR_CREATE + "')")
     public ConnInstanceTO create(final ConnInstanceTO connInstanceTO) {
         if (connInstanceTO.getAdminRealm() == null) {
@@ -93,7 +111,7 @@ public class ConnectorLogic extends AbstractTransactionalLogic<ConnInstanceTO> {
                 connInstanceTO.getAdminRealm());
         securityChecks(effectiveRealms, connInstanceTO.getAdminRealm(), null);
 
-        return binder.getConnInstanceTO(connInstanceDAO.save(binder.getConnInstance(connInstanceTO)));
+        return binder.getConnInstanceTO(doSave(binder.getConnInstance(connInstanceTO)));
     }
 
     @PreAuthorize("hasRole('" + IdMEntitlement.CONNECTOR_UPDATE + "')")
@@ -109,7 +127,7 @@ public class ConnectorLogic extends AbstractTransactionalLogic<ConnInstanceTO> {
                 connInstanceTO.getAdminRealm());
         securityChecks(effectiveRealms, connInstanceTO.getAdminRealm(), connInstanceTO.getKey());
 
-        return binder.getConnInstanceTO(binder.update(connInstanceTO));
+        return binder.getConnInstanceTO(doSave(binder.update(connInstanceTO)));
     }
 
     @PreAuthorize("hasRole('" + IdMEntitlement.CONNECTOR_DELETE + "')")
@@ -133,6 +151,7 @@ public class ConnectorLogic extends AbstractTransactionalLogic<ConnInstanceTO> {
 
         ConnInstanceTO deleted = binder.getConnInstanceTO(connInstance);
         connInstanceDAO.delete(key);
+        connectorManager.unregisterConnector(key);
         return deleted;
     }
 
@@ -201,8 +220,8 @@ public class ConnectorLogic extends AbstractTransactionalLogic<ConnInstanceTO> {
             actual = binder.getConnInstanceTO(existing);
         }
 
-        Set<ObjectClassInfo> objectClassInfo = connFactory.createConnector(
-                connFactory.buildConnInstanceOverride(actual, connInstanceTO.getConf(), Optional.empty())).
+        Set<ObjectClassInfo> objectClassInfo = connectorManager.createConnector(
+                connectorManager.buildConnInstanceOverride(actual, connInstanceTO.getConf(), Optional.empty())).
                 getObjectClassInfo();
 
         return objectClassInfo.stream().map(info -> {
@@ -234,7 +253,7 @@ public class ConnectorLogic extends AbstractTransactionalLogic<ConnInstanceTO> {
             throw SyncopeClientException.build(ClientExceptionType.InvalidRealm);
         }
 
-        connFactory.createConnector(binder.getConnInstance(connInstanceTO)).test();
+        connectorManager.createConnector(binder.getConnInstance(connInstanceTO)).test();
     }
 
     @PreAuthorize("hasRole('" + IdMEntitlement.CONNECTOR_READ + "')")
@@ -246,7 +265,8 @@ public class ConnectorLogic extends AbstractTransactionalLogic<ConnInstanceTO> {
         if (resource == null) {
             throw new NotFoundException("Resource '" + resourceName + '\'');
         }
-        ConnInstanceTO connInstance = binder.getConnInstanceTO(connFactory.getConnector(resource).getConnInstance());
+        ConnInstanceTO connInstance = binder.
+                getConnInstanceTO(connectorManager.getConnector(resource).getConnInstance());
         connInstance.setKey(resource.getConnector().getKey());
         return connInstance;
     }
@@ -254,8 +274,8 @@ public class ConnectorLogic extends AbstractTransactionalLogic<ConnInstanceTO> {
     @PreAuthorize("hasRole('" + IdMEntitlement.CONNECTOR_RELOAD + "')")
     @Transactional(readOnly = true)
     public void reload() {
-        connFactory.unload();
-        connFactory.load();
+        connectorManager.unload();
+        connectorManager.load();
     }
 
     @Override
diff --git a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/IdMLogicContext.java b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/IdMLogicContext.java
new file mode 100644
index 0000000..b29e181
--- /dev/null
+++ b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/IdMLogicContext.java
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.logic;
+
+import org.apache.syncope.core.logic.init.IdMEntitlementLoader;
+import org.apache.syncope.core.logic.init.IdMImplementationTypeLoader;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.ConnInstanceDAO;
+import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.dao.RemediationDAO;
+import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
+import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
+import org.apache.syncope.core.provisioning.api.ConnectorManager;
+import org.apache.syncope.core.provisioning.api.MappingManager;
+import org.apache.syncope.core.provisioning.api.VirAttrHandler;
+import org.apache.syncope.core.provisioning.api.data.ConnInstanceDataBinder;
+import org.apache.syncope.core.provisioning.api.data.RemediationDataBinder;
+import org.apache.syncope.core.provisioning.api.data.ResourceDataBinder;
+import org.apache.syncope.core.provisioning.java.pushpull.InboundMatcher;
+import org.apache.syncope.core.provisioning.java.pushpull.OutboundMatcher;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class IdMLogicContext {
+
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
+    private ExternalResourceDAO resourceDAO;
+
+    @Autowired
+    private ConnInstanceDAO connInstanceDAO;
+
+    @Autowired
+    private VirSchemaDAO virSchemaDAO;
+
+    @Autowired
+    private VirAttrHandler virAttrHandler;
+
+    @Autowired
+    private ConnInstanceDataBinder connInstanceDataBinder;
+
+    @Autowired
+    private ConnectorManager connectorManager;
+
+    @Autowired
+    private InboundMatcher inboundMatcher;
+
+    @Autowired
+    private OutboundMatcher outboundMatcher;
+
+    @Autowired
+    private MappingManager mappingManager;
+
+    @Autowired
+    private AnyUtilsFactory anyUtilsFactory;
+
+    @ConditionalOnMissingBean
+    @Bean
+    public IdMEntitlementLoader idmEntitlementLoader() {
+        return new IdMEntitlementLoader();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public IdMImplementationTypeLoader idmImplementationTypeLoader() {
+        return new IdMImplementationTypeLoader();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public ConnectorLogic connectorLogic(final ConnIdBundleManager connIdBundleManager) {
+        return new ConnectorLogic(
+                connIdBundleManager,
+                connectorManager,
+                resourceDAO,
+                connInstanceDAO,
+                connInstanceDataBinder);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public ReconciliationLogic reconciliationLogic(
+            final RealmDAO realmDAO,
+            final PlainSchemaDAO plainSchemaDAO,
+            final DerSchemaDAO derSchemaDAO,
+            final AnySearchDAO anySearchDAO) {
+
+        return new ReconciliationLogic(
+                anyUtilsFactory,
+                anyTypeDAO,
+                resourceDAO,
+                realmDAO,
+                plainSchemaDAO,
+                derSchemaDAO,
+                virSchemaDAO,
+                anySearchDAO,
+                virAttrHandler,
+                mappingManager,
+                inboundMatcher,
+                outboundMatcher,
+                connectorManager);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public RemediationLogic remediationLogic(
+            final UserLogic userLogic,
+            final GroupLogic groupLogic,
+            final AnyObjectLogic anyObjectLogic,
+            final RemediationDataBinder binder,
+            final RemediationDAO remediationDAO) {
+
+        return new RemediationLogic(userLogic, groupLogic, anyObjectLogic, binder, remediationDAO);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public ResourceLogic resourceLogic(final ResourceDataBinder resourceDataBinder) {
+        return new ResourceLogic(
+                resourceDAO,
+                anyTypeDAO,
+                connInstanceDAO,
+                virSchemaDAO,
+                virAttrHandler,
+                resourceDataBinder,
+                connInstanceDataBinder,
+                outboundMatcher,
+                mappingManager,
+                connectorManager,
+                anyUtilsFactory);
+    }
+}
diff --git a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java
index b33cb81..8fe2fe4 100644
--- a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java
+++ b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java
@@ -53,7 +53,6 @@ import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount;
-import org.apache.syncope.core.provisioning.api.ConnectorFactory;
 import org.apache.syncope.core.provisioning.api.MappingManager;
 import org.apache.syncope.core.provisioning.api.VirAttrHandler;
 import org.apache.syncope.common.lib.to.ProvisioningReport;
@@ -70,6 +69,7 @@ import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
+import org.apache.syncope.core.provisioning.api.ConnectorManager;
 import org.apache.syncope.core.provisioning.api.pushpull.ConstantReconFilterBuilder;
 import org.apache.syncope.core.provisioning.api.pushpull.KeyValueReconFilterBuilder;
 import org.apache.syncope.core.provisioning.api.pushpull.ReconFilterBuilder;
@@ -100,55 +100,69 @@ import org.identityconnectors.framework.common.objects.Uid;
 import org.identityconnectors.framework.common.objects.filter.Filter;
 import org.identityconnectors.framework.spi.SearchResultsHandler;
 import org.quartz.JobExecutionException;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.beans.factory.support.AbstractBeanDefinition;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
 
-    @Autowired
-    private AnyUtilsFactory anyUtilsFactory;
+    protected final AnyUtilsFactory anyUtilsFactory;
 
-    @Autowired
-    private AnyTypeDAO anyTypeDAO;
+    protected final AnyTypeDAO anyTypeDAO;
 
-    @Autowired
-    private ExternalResourceDAO resourceDAO;
+    protected final ExternalResourceDAO resourceDAO;
 
-    @Autowired
-    private RealmDAO realmDAO;
+    protected final RealmDAO realmDAO;
 
-    @Autowired
-    private PlainSchemaDAO plainSchemaDAO;
+    protected final PlainSchemaDAO plainSchemaDAO;
 
-    @Autowired
-    private DerSchemaDAO derSchemaDAO;
+    protected final DerSchemaDAO derSchemaDAO;
 
-    @Autowired
-    private VirSchemaDAO virSchemaDAO;
+    protected final VirSchemaDAO virSchemaDAO;
 
-    @Autowired
-    private AnySearchDAO searchDAO;
+    protected final AnySearchDAO anySearchDAO;
 
-    @Autowired
-    private VirAttrHandler virAttrHandler;
+    protected final VirAttrHandler virAttrHandler;
 
-    @Autowired
-    private MappingManager mappingManager;
+    protected final MappingManager mappingManager;
 
-    @Autowired
-    private InboundMatcher inboundMatcher;
+    protected final InboundMatcher inboundMatcher;
 
-    @Autowired
-    private OutboundMatcher outboundMatcher;
+    protected final OutboundMatcher outboundMatcher;
 
-    @Autowired
-    private ConnectorFactory connFactory;
+    protected final ConnectorManager connectorManager;
 
-    private Provision getProvision(final String anyTypeKey, final String resourceKey) {
+    public ReconciliationLogic(
+            final AnyUtilsFactory anyUtilsFactory,
+            final AnyTypeDAO anyTypeDAO,
+            final ExternalResourceDAO resourceDAO,
+            final RealmDAO realmDAO,
+            final PlainSchemaDAO plainSchemaDAO,
+            final DerSchemaDAO derSchemaDAO,
+            final VirSchemaDAO virSchemaDAO,
+            final AnySearchDAO anySearchDAO,
+            final VirAttrHandler virAttrHandler,
+            final MappingManager mappingManager,
+            final InboundMatcher inboundMatcher,
+            final OutboundMatcher outboundMatcher,
+            final ConnectorManager connectorManager) {
+
+        this.anyUtilsFactory = anyUtilsFactory;
+        this.anyTypeDAO = anyTypeDAO;
+        this.resourceDAO = resourceDAO;
+        this.realmDAO = realmDAO;
+        this.plainSchemaDAO = plainSchemaDAO;
+        this.derSchemaDAO = derSchemaDAO;
+        this.virSchemaDAO = virSchemaDAO;
+        this.anySearchDAO = anySearchDAO;
+        this.virAttrHandler = virAttrHandler;
+        this.mappingManager = mappingManager;
+        this.inboundMatcher = inboundMatcher;
+        this.outboundMatcher = outboundMatcher;
+        this.connectorManager = connectorManager;
+    }
+
+    protected Provision getProvision(final String anyTypeKey, final String resourceKey) {
         AnyType anyType = anyTypeDAO.find(anyTypeKey);
         if (anyType == null) {
             throw new NotFoundException("AnyType '" + anyTypeKey + "'");
@@ -168,7 +182,7 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
         return provision;
     }
 
-    private ConnObjectTO getOnSyncope(
+    protected ConnObjectTO getOnSyncope(
             final MappingItem connObjectKeyItem,
             final String connObjectKeyValue,
             final Set<Attribute> attrs) {
@@ -182,7 +196,7 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
         return connObjectTO;
     }
 
-    private ConnObjectTO getOnSyncope(
+    protected ConnObjectTO getOnSyncope(
             final Any<?> any,
             final MappingItem connObjectKeyItem,
             final Provision provision) {
@@ -192,7 +206,7 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
         return getOnSyncope(connObjectKeyItem, prepared.getLeft(), prepared.getRight());
     }
 
-    private ConnObjectTO getOnSyncope(
+    protected ConnObjectTO getOnSyncope(
             final LinkedAccount account,
             final MappingItem connObjectKeyItem,
             final Provision provision) {
@@ -202,7 +216,7 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
         return getOnSyncope(connObjectKeyItem, account.getConnObjectKeyValue(), attrs);
     }
 
-    private Any<?> getAny(final Provision provision, final String anyKey) {
+    protected Any<?> getAny(final Provision provision, final String anyKey) {
         AnyDAO<Any<?>> dao = anyUtilsFactory.getInstance(provision.getAnyType().getKind()).dao();
         Any<?> any = SyncopeConstants.UUID_PATTERN.matcher(anyKey).matches()
                 ? dao.authFind(anyKey)
@@ -236,7 +250,7 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
         status.setRealm(any.getRealm().getFullPath());
         status.setOnSyncope(getOnSyncope(any, connObjectKeyItem, provision));
 
-        List<ConnectorObject> connObjs = outboundMatcher.match(connFactory.getConnector(
+        List<ConnectorObject> connObjs = outboundMatcher.match(connectorManager.getConnector(
                 provision.getResource()), any, provision, Optional.of(moreAttrsToGet.toArray(new String[] {})));
         if (!connObjs.isEmpty()) {
             status.setOnResource(ConnObjectUtils.getConnObjectTO(
@@ -252,7 +266,7 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
         return status;
     }
 
-    private SyncDeltaBuilder syncDeltaBuilder(
+    protected SyncDeltaBuilder syncDeltaBuilder(
             final Provision provision,
             final Filter filter,
             final Set<String> moreAttrsToGet) {
@@ -266,7 +280,7 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
                 setToken(new SyncToken("")).
                 setDeltaType(SyncDeltaType.CREATE_OR_UPDATE).
                 setObjectClass(provision.getObjectClass());
-        connFactory.getConnector(provision.getResource()).
+        connectorManager.getConnector(provision.getResource()).
                 search(provision.getObjectClass(), filter, new SearchResultsHandler() {
 
                     @Override
@@ -330,7 +344,7 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
         return status;
     }
 
-    private SyncopeSinglePushExecutor singlePushExecutor() {
+    protected SyncopeSinglePushExecutor singlePushExecutor() {
         return (SyncopeSinglePushExecutor) ApplicationContextProvider.getBeanFactory().
                 createBean(SinglePushJobDelegate.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
     }
@@ -349,9 +363,10 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
         try {
             results.addAll(singlePushExecutor().push(
                     provision,
-                    connFactory.getConnector(provision.getResource()),
+                    connectorManager.getConnector(provision.getResource()),
                     getAny(provision, anyKey),
-                    pushTask));
+                    pushTask,
+                    AuthContextUtils.getUsername()));
             if (!results.isEmpty() && results.get(0).getStatus() == ProvisioningReport.Status.FAILURE) {
                 sce.getElements().add(results.get(0).getMessage());
             }
@@ -387,18 +402,20 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
                     if (match.getMatchTarget() == MatchType.ANY) {
                         results.addAll(singlePushExecutor().push(
                                 provision,
-                                connFactory.getConnector(provision.getResource()),
+                                connectorManager.getConnector(provision.getResource()),
                                 match.getAny(),
-                                pushTask));
+                                pushTask,
+                                AuthContextUtils.getUsername()));
                         if (!results.isEmpty() && results.get(0).getStatus() == ProvisioningReport.Status.FAILURE) {
                             sce.getElements().add(results.get(0).getMessage());
                         }
                     } else {
                         ProvisioningReport result = singlePushExecutor().push(
                                 provision,
-                                connFactory.getConnector(provision.getResource()),
+                                connectorManager.getConnector(provision.getResource()),
                                 match.getLinkedAccount(),
-                                pushTask);
+                                pushTask,
+                                AuthContextUtils.getUsername());
                         if (result.getStatus() == ProvisioningReport.Status.FAILURE) {
                             sce.getElements().add(result.getMessage());
                         } else {
@@ -418,7 +435,7 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
         return results;
     }
 
-    private List<ProvisioningReport> pull(
+    protected List<ProvisioningReport> pull(
             final Provision provision,
             final ReconFilterBuilder reconFilterBuilder,
             final Set<String> moreAttrsToGet,
@@ -437,7 +454,7 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
 
             results.addAll(executor.pull(
                     provision,
-                    connFactory.getConnector(provision.getResource()),
+                    connectorManager.getConnector(provision.getResource()),
                     reconFilterBuilder,
                     moreAttrsToGet,
                     pullTask));
@@ -504,7 +521,7 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
                 pullTask);
     }
 
-    private CsvSchema.Builder csvSchema(final AbstractCSVSpec spec) {
+    protected CsvSchema.Builder csvSchema(final AbstractCSVSpec spec) {
         CsvSchema.Builder schemaBuilder = new CsvSchema.Builder().setUseHeader(true).
                 setColumnSeparator(spec.getColumnSeparator()).
                 setArrayElementSeparator(spec.getArrayElementSeparator()).
@@ -557,15 +574,15 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
         if (spec.getIgnorePaging()) {
             matching = new ArrayList<>();
 
-            int count = searchDAO.count(adminRealms, effectiveCond, anyType.getKind());
+            int count = anySearchDAO.count(adminRealms, effectiveCond, anyType.getKind());
             int pages = (count / AnyDAO.DEFAULT_PAGE_SIZE) + 1;
 
             for (int p = 1; p <= pages; p++) {
-                matching.addAll(searchDAO.search(adminRealms, effectiveCond,
+                matching.addAll(anySearchDAO.search(adminRealms, effectiveCond,
                         p, AnyDAO.DEFAULT_PAGE_SIZE, orderBy, anyType.getKind()));
             }
         } else {
-            matching = searchDAO.search(adminRealms, effectiveCond, page, size, orderBy, anyType.getKind());
+            matching = anySearchDAO.search(adminRealms, effectiveCond, page, size, orderBy, anyType.getKind());
         }
 
         List<String> columns = new ArrayList<>();
diff --git a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/RemediationLogic.java b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/RemediationLogic.java
index ffeab22..274a90e 100644
--- a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/RemediationLogic.java
+++ b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/RemediationLogic.java
@@ -41,28 +41,34 @@ import org.apache.syncope.core.persistence.api.dao.RemediationDAO;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.entity.Remediation;
 import org.apache.syncope.core.provisioning.api.data.RemediationDataBinder;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class RemediationLogic extends AbstractLogic<RemediationTO> {
 
-    @Autowired
-    private UserLogic userLogic;
+    protected final UserLogic userLogic;
 
-    @Autowired
-    private GroupLogic groupLogic;
+    protected final GroupLogic groupLogic;
 
-    @Autowired
-    private AnyObjectLogic anyObjectLogic;
+    protected final AnyObjectLogic anyObjectLogic;
 
-    @Autowired
-    private RemediationDataBinder binder;
+    protected final RemediationDataBinder binder;
 
-    @Autowired
-    private RemediationDAO remediationDAO;
+    protected final RemediationDAO remediationDAO;
+
+    public RemediationLogic(
+            final UserLogic userLogic,
+            final GroupLogic groupLogic,
+            final AnyObjectLogic anyObjectLogic,
+            final RemediationDataBinder binder,
+            final RemediationDAO remediationDAO) {
+
+        this.userLogic = userLogic;
+        this.groupLogic = groupLogic;
+        this.anyObjectLogic = anyObjectLogic;
+        this.binder = binder;
+        this.remediationDAO = remediationDAO;
+    }
 
     @PreAuthorize("hasRole('" + IdMEntitlement.REMEDIATION_LIST + "')")
     @Transactional(readOnly = true)
diff --git a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
index e5859c4..6f7dcb0 100644
--- a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
+++ b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
@@ -40,7 +40,6 @@ import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.apache.syncope.core.provisioning.api.Connector;
-import org.apache.syncope.core.provisioning.api.ConnectorFactory;
 import org.apache.syncope.core.provisioning.api.data.ResourceDataBinder;
 import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
@@ -53,6 +52,7 @@ import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.provisioning.api.ConnectorManager;
 import org.apache.syncope.core.provisioning.api.MappingManager;
 import org.apache.syncope.core.provisioning.api.VirAttrHandler;
 import org.apache.syncope.core.provisioning.api.data.ConnInstanceDataBinder;
@@ -67,54 +67,76 @@ import org.identityconnectors.framework.common.objects.OperationOptions;
 import org.identityconnectors.framework.common.objects.SearchResult;
 import org.identityconnectors.framework.common.objects.filter.Filter;
 import org.identityconnectors.framework.spi.SearchResultsHandler;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
 
-    @Autowired
-    private ExternalResourceDAO resourceDAO;
+    protected final ExternalResourceDAO resourceDAO;
 
-    @Autowired
-    private AnyTypeDAO anyTypeDAO;
+    protected final AnyTypeDAO anyTypeDAO;
 
-    @Autowired
-    private ConnInstanceDAO connInstanceDAO;
+    protected final ConnInstanceDAO connInstanceDAO;
 
-    @Autowired
-    private VirSchemaDAO virSchemaDAO;
+    protected final VirSchemaDAO virSchemaDAO;
 
-    @Autowired
-    private VirAttrHandler virAttrHandler;
+    protected final VirAttrHandler virAttrHandler;
 
-    @Autowired
-    private ResourceDataBinder binder;
+    protected final ResourceDataBinder binder;
 
-    @Autowired
-    private ConnInstanceDataBinder connInstanceDataBinder;
+    protected final ConnInstanceDataBinder connInstanceDataBinder;
 
-    @Autowired
-    private OutboundMatcher outboundMatcher;
+    protected final OutboundMatcher outboundMatcher;
 
-    @Autowired
-    private MappingManager mappingManager;
+    protected final MappingManager mappingManager;
 
-    @Autowired
-    private ConnectorFactory connFactory;
+    protected final ConnectorManager connectorManager;
 
-    @Autowired
-    private AnyUtilsFactory anyUtilsFactory;
+    protected final AnyUtilsFactory anyUtilsFactory;
 
-    protected static void securityChecks(final Set<String> effectiveRealms, final String realm, final String key) {
+    public ResourceLogic(
+            final ExternalResourceDAO resourceDAO,
+            final AnyTypeDAO anyTypeDAO,
+            final ConnInstanceDAO connInstanceDAO,
+            final VirSchemaDAO virSchemaDAO,
+            final VirAttrHandler virAttrHandler,
+            final ResourceDataBinder binder,
+            final ConnInstanceDataBinder connInstanceDataBinder,
+            final OutboundMatcher outboundMatcher,
+            final MappingManager mappingManager,
+            final ConnectorManager connectorManager,
+            final AnyUtilsFactory anyUtilsFactory) {
+
+        this.resourceDAO = resourceDAO;
+        this.anyTypeDAO = anyTypeDAO;
+        this.connInstanceDAO = connInstanceDAO;
+        this.virSchemaDAO = virSchemaDAO;
+        this.virAttrHandler = virAttrHandler;
+        this.binder = binder;
+        this.connInstanceDataBinder = connInstanceDataBinder;
+        this.outboundMatcher = outboundMatcher;
+        this.mappingManager = mappingManager;
+        this.connectorManager = connectorManager;
+        this.anyUtilsFactory = anyUtilsFactory;
+    }
+
+    protected void securityChecks(final Set<String> effectiveRealms, final String realm, final String key) {
         boolean authorized = effectiveRealms.stream().anyMatch(realm::startsWith);
         if (!authorized) {
             throw new DelegatedAdministrationException(realm, ExternalResource.class.getSimpleName(), key);
         }
     }
 
+    protected ExternalResource doSave(final ExternalResource resource) {
+        ExternalResource merged = resourceDAO.save(resource);
+        try {
+            connectorManager.registerConnector(merged);
+        } catch (NotFoundException e) {
+            LOG.error("While registering connector for resource", e);
+        }
+        return merged;
+    }
+
     @PreAuthorize("hasRole('" + IdMEntitlement.RESOURCE_CREATE + "')")
     public ResourceTO create(final ResourceTO resourceTO) {
         if (StringUtils.isBlank(resourceTO.getKey())) {
@@ -139,7 +161,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
             throw new DuplicateException(resourceTO.getKey());
         }
 
-        return binder.getResourceTO(resourceDAO.save(binder.create(resourceTO)));
+        return binder.getResourceTO(doSave(binder.create(resourceTO)));
     }
 
     @PreAuthorize("hasRole('" + IdMEntitlement.RESOURCE_UPDATE + "')")
@@ -154,7 +176,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
                 resource.getConnector().getAdminRealm().getFullPath());
         securityChecks(effectiveRealms, resource.getConnector().getAdminRealm().getFullPath(), resource.getKey());
 
-        return binder.getResourceTO(resourceDAO.save(binder.update(resource, resourceTO)));
+        return binder.getResourceTO(doSave(binder.update(resource, resourceTO)));
     }
 
     @PreAuthorize("hasRole('" + IdMEntitlement.RESOURCE_UPDATE + "')")
@@ -166,7 +188,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
 
         Connector connector;
         try {
-            connector = connFactory.getConnector(resource);
+            connector = connectorManager.getConnector(resource);
         } catch (Exception e) {
             SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidConnInstance);
             sce.getElements().add(e.getMessage());
@@ -197,7 +219,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
                 resource.getConnector().getAdminRealm().getFullPath());
         securityChecks(effectiveRealms, resource.getConnector().getAdminRealm().getFullPath(), resource.getKey());
 
-        resourceDAO.save(resource);
+        doSave(resource);
     }
 
     @PreAuthorize("hasRole('" + IdMEntitlement.RESOURCE_UPDATE + "')")
@@ -230,7 +252,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
                 resource.getConnector().getAdminRealm().getFullPath());
         securityChecks(effectiveRealms, resource.getConnector().getAdminRealm().getFullPath(), resource.getKey());
 
-        resourceDAO.save(resource);
+        doSave(resource);
     }
 
     @PreAuthorize("hasRole('" + IdMEntitlement.RESOURCE_DELETE + "')")
@@ -269,7 +291,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
         return resourceDAO.findAll().stream().map(binder::getResourceTO).collect(Collectors.toList());
     }
 
-    private Provision getProvision(final String resourceKey, final String anyTypeKey) {
+    protected Provision getProvision(final String resourceKey, final String anyTypeKey) {
         ExternalResource resource = resourceDAO.find(resourceKey);
         if (resource == null) {
             throw new NotFoundException("Resource '" + resourceKey + '\'');
@@ -323,7 +345,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
 
         // 2. find on resource
         List<ConnectorObject> connObjs = outboundMatcher.match(
-                connFactory.getConnector(provision.getResource()), any, provision, Optional.empty());
+                connectorManager.getConnector(provision.getResource()), any, provision, Optional.empty());
         if (connObjs.isEmpty()) {
             throw new NotFoundException(
                     "Object " + any + " with class " + provision.getObjectClass()
@@ -355,7 +377,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
                 + " on resource '" + provision.getResource().getKey() + "'"));
 
         return outboundMatcher.matchByConnObjectKeyValue(
-                connFactory.getConnector(provision.getResource()),
+                connectorManager.getConnector(provision.getResource()),
                 connObjectKeyItem,
                 connObjectKeyValue,
                 provision,
@@ -408,7 +430,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
         }
 
         List<ConnObjectTO> connObjects = new ArrayList<>();
-        SearchResult searchResult = connFactory.getConnector(resource).
+        SearchResult searchResult = connectorManager.getConnector(resource).
                 search(objectClass, filter, new SearchResultsHandler() {
 
                     private int count;
@@ -440,8 +462,8 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
             throw new NotFoundException("Connector '" + resourceTO.getConnector() + '\'');
         }
 
-        connFactory.createConnector(
-                connFactory.buildConnInstanceOverride(
+        connectorManager.createConnector(
+                connectorManager.buildConnInstanceOverride(
                         connInstanceDataBinder.getConnInstanceTO(connInstance),
                         resourceTO.getConfOverride(),
                         resourceTO.isOverrideCapabilities()
diff --git a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/init/IdMEntitlementLoader.java b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/init/IdMEntitlementLoader.java
index bb4a3fb..e483977 100644
--- a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/init/IdMEntitlementLoader.java
+++ b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/init/IdMEntitlementLoader.java
@@ -21,9 +21,7 @@ package org.apache.syncope.core.logic.init;
 import org.apache.syncope.common.lib.types.EntitlementsHolder;
 import org.apache.syncope.common.lib.types.IdMEntitlement;
 import org.apache.syncope.core.persistence.api.SyncopeCoreLoader;
-import org.springframework.stereotype.Component;
 
-@Component
 public class IdMEntitlementLoader implements SyncopeCoreLoader {
 
     @Override
diff --git a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/init/IdMImplementationTypeLoader.java b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/init/IdMImplementationTypeLoader.java
index 1a64ee1..db35452 100644
--- a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/init/IdMImplementationTypeLoader.java
+++ b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/init/IdMImplementationTypeLoader.java
@@ -22,9 +22,7 @@ import org.apache.syncope.common.lib.types.IdMImplementationType;
 import org.apache.syncope.common.lib.types.ImplementationTypesHolder;
 import org.apache.syncope.core.persistence.api.SyncopeCoreLoader;
 import org.springframework.core.Ordered;
-import org.springframework.stereotype.Component;
 
-@Component
 public class IdMImplementationTypeLoader implements SyncopeCoreLoader {
 
     @Override
diff --git a/core/idrepo/logic/src/main/resources/META-INF/spring.factories b/core/idm/logic/src/main/resources/META-INF/spring.factories
similarity index 94%
copy from core/idrepo/logic/src/main/resources/META-INF/spring.factories
copy to core/idm/logic/src/main/resources/META-INF/spring.factories
index eb5b93f..44f2c44 100644
--- a/core/idrepo/logic/src/main/resources/META-INF/spring.factories
+++ b/core/idm/logic/src/main/resources/META-INF/spring.factories
@@ -16,4 +16,4 @@
 # under the License.
 
 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-  org.apache.syncope.core.logic.LogicContext
+  org.apache.syncope.core.logic.IdMLogicContext
diff --git a/core/idm/logic/src/test/java/org/apache/syncope/core/logic/DummyConfParamOps.java b/core/idm/logic/src/test/java/org/apache/syncope/core/logic/DummyConfParamOps.java
index ca3a1ac..7ebb0b1 100644
--- a/core/idm/logic/src/test/java/org/apache/syncope/core/logic/DummyConfParamOps.java
+++ b/core/idm/logic/src/test/java/org/apache/syncope/core/logic/DummyConfParamOps.java
@@ -20,9 +20,7 @@ package org.apache.syncope.core.logic;
 
 import java.util.Map;
 import org.apache.syncope.common.keymaster.client.api.ConfParamOps;
-import org.springframework.stereotype.Component;
 
-@Component
 public class DummyConfParamOps implements ConfParamOps {
 
     @Override
diff --git a/core/idm/logic/src/test/java/org/apache/syncope/core/logic/DummyDomainOps.java b/core/idm/logic/src/test/java/org/apache/syncope/core/logic/DummyDomainOps.java
index 22e90bf..840c11e 100644
--- a/core/idm/logic/src/test/java/org/apache/syncope/core/logic/DummyDomainOps.java
+++ b/core/idm/logic/src/test/java/org/apache/syncope/core/logic/DummyDomainOps.java
@@ -23,14 +23,14 @@ import org.apache.syncope.common.keymaster.client.api.DomainOps;
 import org.apache.syncope.common.keymaster.client.api.model.Domain;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.core.persistence.api.DomainRegistry;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
 
-@Component
 public class DummyDomainOps implements DomainOps {
 
-    @Autowired
-    private DomainRegistry domainRegistry;
+    private final DomainRegistry domainRegistry;
+
+    public DummyDomainOps(final DomainRegistry domainRegistry) {
+        this.domainRegistry = domainRegistry;
+    }
 
     @Override
     public List<Domain> list() {
diff --git a/core/idm/logic/src/test/java/org/apache/syncope/core/logic/DummyServiceOps.java b/core/idm/logic/src/test/java/org/apache/syncope/core/logic/DummyServiceOps.java
index ce88ef3..efdedf0 100644
--- a/core/idm/logic/src/test/java/org/apache/syncope/core/logic/DummyServiceOps.java
+++ b/core/idm/logic/src/test/java/org/apache/syncope/core/logic/DummyServiceOps.java
@@ -21,9 +21,7 @@ package org.apache.syncope.core.logic;
 import java.util.List;
 import org.apache.syncope.common.keymaster.client.api.ServiceOps;
 import org.apache.syncope.common.keymaster.client.api.model.NetworkService;
-import org.springframework.stereotype.Component;
 
-@Component
 public class DummyServiceOps implements ServiceOps {
 
     @Override
diff --git a/core/idm/logic/src/test/java/org/apache/syncope/core/logic/IdMLogicTestContext.java b/core/idm/logic/src/test/java/org/apache/syncope/core/logic/IdMLogicTestContext.java
index 3d51425..92b98d9 100644
--- a/core/idm/logic/src/test/java/org/apache/syncope/core/logic/IdMLogicTestContext.java
+++ b/core/idm/logic/src/test/java/org/apache/syncope/core/logic/IdMLogicTestContext.java
@@ -18,27 +18,61 @@
  */
 package org.apache.syncope.core.logic;
 
+import org.apache.syncope.common.keymaster.client.api.ConfParamOps;
+import org.apache.syncope.common.keymaster.client.api.DomainOps;
+import org.apache.syncope.common.keymaster.client.api.ServiceOps;
+import org.apache.syncope.core.persistence.api.DomainHolder;
+import org.apache.syncope.core.persistence.api.DomainRegistry;
 import org.apache.syncope.core.persistence.api.ImplementationLookup;
+import org.apache.syncope.core.persistence.api.content.ContentLoader;
+import org.apache.syncope.core.persistence.jpa.MasterDomain;
 import org.apache.syncope.core.persistence.jpa.PersistenceContext;
+import org.apache.syncope.core.persistence.jpa.StartupDomainLoader;
 import org.apache.syncope.core.provisioning.java.ProvisioningContext;
 import org.apache.syncope.core.spring.security.SecurityContext;
 import org.apache.syncope.core.workflow.java.WorkflowContext;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ConfigurableApplicationContext;
 import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Import;
-import org.springframework.context.annotation.Primary;
 import org.springframework.context.annotation.PropertySource;
 
 @PropertySource("classpath:core-test.properties")
-@Import({ SecurityContext.class, PersistenceContext.class, ProvisioningContext.class, WorkflowContext.class })
-@ComponentScan("org.apache.syncope.core.logic")
+@Import({ IdRepoLogicContext.class, IdMLogicContext.class, SecurityContext.class,
+    PersistenceContext.class, MasterDomain.class, ProvisioningContext.class, WorkflowContext.class })
 @Configuration
 public class IdMLogicTestContext {
 
-    @Primary
+    @Bean
+    @Autowired
+    public TestInitializer testInitializer(
+            final StartupDomainLoader domainLoader,
+            final DomainHolder domainHolder,
+            final ContentLoader contentLoader,
+            final ConfigurableApplicationContext ctx) {
+
+        return new TestInitializer(domainLoader, domainHolder, contentLoader, ctx);
+    }
+
     @Bean
     public ImplementationLookup implementationLookup() {
         return new DummyImplementationLookup();
     }
+
+    @Bean
+    public ConfParamOps confParamOps() {
+        return new DummyConfParamOps();
+    }
+
+    @Bean
+    @Autowired
+    public DomainOps domainOps(final DomainRegistry domainRegistry) {
+        return new DummyDomainOps(domainRegistry);
+    }
+
+    @Bean
+    public ServiceOps serviceOps() {
+        return new DummyServiceOps();
+    }
 }
diff --git a/core/idm/logic/src/test/java/org/apache/syncope/core/logic/TestInitializer.java b/core/idm/logic/src/test/java/org/apache/syncope/core/logic/TestInitializer.java
index 1a4a652..05ad894 100644
--- a/core/idm/logic/src/test/java/org/apache/syncope/core/logic/TestInitializer.java
+++ b/core/idm/logic/src/test/java/org/apache/syncope/core/logic/TestInitializer.java
@@ -23,33 +23,31 @@ import org.apache.syncope.core.persistence.api.DomainHolder;
 import org.apache.syncope.core.persistence.api.content.ContentLoader;
 import org.apache.syncope.core.persistence.jpa.StartupDomainLoader;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
-import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.InitializingBean;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.support.DefaultListableBeanFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
 import org.springframework.context.ConfigurableApplicationContext;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.support.TransactionSynchronizationManager;
 
-@Component
-public class TestInitializer implements InitializingBean, ApplicationContextAware {
+public class TestInitializer implements InitializingBean {
 
-    private ConfigurableApplicationContext ctx;
+    private final StartupDomainLoader domainLoader;
 
-    @Autowired
-    private StartupDomainLoader domainLoader;
+    private final DomainHolder domainHolder;
 
-    @Autowired
-    private DomainHolder domainHolder;
+    private final ContentLoader contentLoader;
 
-    @Autowired
-    private ContentLoader contentLoader;
+    private final ConfigurableApplicationContext ctx;
 
-    @Override
-    public void setApplicationContext(final ApplicationContext ctx) throws BeansException {
-        this.ctx = (ConfigurableApplicationContext) ctx;
+    public TestInitializer(
+            final StartupDomainLoader domainLoader,
+            final DomainHolder domainHolder,
+            final ContentLoader contentLoader,
+            final ConfigurableApplicationContext ctx) {
+
+        this.domainLoader = domainLoader;
+        this.domainHolder = domainHolder;
+        this.contentLoader = contentLoader;
+        this.ctx = ctx;
     }
 
     @Override
diff --git a/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/IdMRESTCXFContext.java b/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/IdMRESTCXFContext.java
new file mode 100644
index 0000000..3a0ce14
--- /dev/null
+++ b/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/IdMRESTCXFContext.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.rest.cxf;
+
+import org.apache.syncope.common.rest.api.service.ConnectorService;
+import org.apache.syncope.common.rest.api.service.ReconciliationService;
+import org.apache.syncope.common.rest.api.service.RemediationService;
+import org.apache.syncope.common.rest.api.service.ResourceService;
+import org.apache.syncope.core.logic.ConnectorLogic;
+import org.apache.syncope.core.logic.ReconciliationLogic;
+import org.apache.syncope.core.logic.RemediationLogic;
+import org.apache.syncope.core.logic.ResourceLogic;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.search.SearchCondVisitor;
+import org.apache.syncope.core.rest.cxf.service.ConnectorServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.ReconciliationServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.RemediationServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.ResourceServiceImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class IdMRESTCXFContext {
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public ConnectorService connectorService(final ConnectorLogic connectorLogic) {
+        return new ConnectorServiceImpl(connectorLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public ReconciliationService reconciliationService(
+            final SearchCondVisitor searchCondVisitor,
+            final ReconciliationLogic reconciliationLogic) {
+
+        return new ReconciliationServiceImpl(searchCondVisitor, reconciliationLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public RemediationService remediationService(
+            final RemediationLogic remediationLogic,
+            final UserDAO userDAO,
+            final GroupDAO groupDAO,
+            final AnyObjectDAO anyObjectDAO) {
+
+        return new RemediationServiceImpl(remediationLogic, userDAO, groupDAO, anyObjectDAO);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public ResourceService resourceService(final ResourceLogic resourceLogic) {
+        return new ResourceServiceImpl(resourceLogic);
+    }
+}
diff --git a/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java b/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
index 45da758..b9f092d 100644
--- a/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
+++ b/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
@@ -27,14 +27,16 @@ import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.ConnectorService;
 import org.apache.syncope.core.logic.ConnectorLogic;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
-public class ConnectorServiceImpl extends AbstractServiceImpl implements ConnectorService {
+public class ConnectorServiceImpl extends AbstractService implements ConnectorService {
 
-    @Autowired
-    private ConnectorLogic logic;
+    protected final ConnectorLogic logic;
+
+    public ConnectorServiceImpl(final ConnectorLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public Response create(final ConnInstanceTO connInstanceTO) {
diff --git a/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReconciliationServiceImpl.java b/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReconciliationServiceImpl.java
index 0ff718b..5b40610 100644
--- a/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReconciliationServiceImpl.java
+++ b/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReconciliationServiceImpl.java
@@ -48,16 +48,20 @@ import org.apache.syncope.common.rest.api.service.ReconciliationService;
 import org.apache.syncope.core.logic.ReconciliationLogic;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.apache.syncope.core.persistence.api.search.FilterVisitor;
+import org.apache.syncope.core.persistence.api.search.SearchCondVisitor;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.identityconnectors.framework.common.objects.filter.Filter;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
-public class ReconciliationServiceImpl extends AbstractServiceImpl implements ReconciliationService {
+public class ReconciliationServiceImpl extends AbstractSearchService implements ReconciliationService {
 
-    @Autowired
-    private ReconciliationLogic logic;
+    protected final ReconciliationLogic logic;
+
+    public ReconciliationServiceImpl(final SearchCondVisitor searchCondVisitor, final ReconciliationLogic logic) {
+        super(searchCondVisitor);
+        this.logic = logic;
+    }
 
     private void validate(final ReconQuery reconQuery) {
         if ((reconQuery.getAnyKey() == null && reconQuery.getFiql() == null)
diff --git a/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RemediationServiceImpl.java b/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RemediationServiceImpl.java
index a0141c5..f60eaec 100644
--- a/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RemediationServiceImpl.java
+++ b/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RemediationServiceImpl.java
@@ -35,23 +35,30 @@ import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
-public class RemediationServiceImpl extends AbstractServiceImpl implements RemediationService {
+public class RemediationServiceImpl extends AbstractService implements RemediationService {
 
-    @Autowired
-    private RemediationLogic logic;
+    protected final RemediationLogic logic;
 
-    @Autowired
-    private UserDAO userDAO;
+    protected final UserDAO userDAO;
 
-    @Autowired
-    private GroupDAO groupDAO;
+    protected final GroupDAO groupDAO;
 
-    @Autowired
-    private AnyObjectDAO anyObjectDAO;
+    protected final AnyObjectDAO anyObjectDAO;
+
+    public RemediationServiceImpl(
+            final RemediationLogic logic,
+            final UserDAO userDAO,
+            final GroupDAO groupDAO,
+            final AnyObjectDAO anyObjectDAO) {
+
+        this.logic = logic;
+        this.userDAO = userDAO;
+        this.groupDAO = groupDAO;
+        this.anyObjectDAO = anyObjectDAO;
+    }
 
     @Override
     public PagedResult<RemediationTO> list(final RemediationQuery query) {
diff --git a/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java b/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java
index 9b80531..1acbf88 100644
--- a/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java
+++ b/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java
@@ -44,14 +44,16 @@ import org.apache.syncope.core.logic.ResourceLogic;
 import org.apache.syncope.core.persistence.api.search.FilterVisitor;
 import org.identityconnectors.framework.common.objects.SearchResult;
 import org.identityconnectors.framework.common.objects.filter.Filter;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
-public class ResourceServiceImpl extends AbstractServiceImpl implements ResourceService {
+public class ResourceServiceImpl extends AbstractService implements ResourceService {
 
-    @Autowired
-    private ResourceLogic logic;
+    protected final ResourceLogic logic;
+
+    public ResourceServiceImpl(final ResourceLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public Response create(final ResourceTO resourceTO) {
diff --git a/ext/saml2sp4ui/logic/src/main/resources/META-INF/spring.factories b/core/idm/rest-cxf/src/main/resources/META-INF/spring.factories
similarity index 94%
copy from ext/saml2sp4ui/logic/src/main/resources/META-INF/spring.factories
copy to core/idm/rest-cxf/src/main/resources/META-INF/spring.factories
index 6cb5b1c..a25165f 100644
--- a/ext/saml2sp4ui/logic/src/main/resources/META-INF/spring.factories
+++ b/core/idm/rest-cxf/src/main/resources/META-INF/spring.factories
@@ -16,4 +16,4 @@
 # under the License.
 
 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-  org.apache.syncope.core.logic.SAML2SP4UIContext
+  org.apache.syncope.core.rest.cxf.IdMRESTCXFContext
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
index c14d668..47b393e 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
@@ -40,23 +40,29 @@ import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.provisioning.api.LogicActions;
 import org.apache.syncope.core.spring.ImplementationManager;
-import org.springframework.beans.factory.annotation.Autowired;
 
 public abstract class AbstractAnyLogic<TO extends AnyTO, C extends AnyCR, U extends AnyUR>
         extends AbstractResourceAssociator<TO> {
 
     protected static final String REST_CONTEXT = "REST";
 
-    @Autowired
-    private RealmDAO realmDAO;
+    protected final RealmDAO realmDAO;
 
-    @Autowired
-    private AnyTypeDAO anyTypeDAO;
+    protected final AnyTypeDAO anyTypeDAO;
 
-    @Autowired
-    private TemplateUtils templateUtils;
+    protected final TemplateUtils templateUtils;
 
-    private static List<LogicActions> getActions(final Realm realm) {
+    public AbstractAnyLogic(
+            final RealmDAO realmDAO,
+            final AnyTypeDAO anyTypeDAO,
+            final TemplateUtils templateUtils) {
+
+        this.realmDAO = realmDAO;
+        this.anyTypeDAO = anyTypeDAO;
+        this.templateUtils = templateUtils;
+    }
+
+    protected List<LogicActions> getActions(final Realm realm) {
         List<LogicActions> actions = new ArrayList<>();
 
         realm.getActions().forEach(impl -> {
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AbstractExecutableLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AbstractExecutableLogic.java
index aa69180..36f76ba 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AbstractExecutableLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AbstractExecutableLogic.java
@@ -27,9 +27,15 @@ import org.apache.syncope.common.lib.to.JobTO;
 import org.apache.syncope.common.lib.types.JobAction;
 import org.apache.syncope.common.rest.api.batch.BatchResponseItem;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.provisioning.api.job.JobManager;
+import org.springframework.scheduling.quartz.SchedulerFactoryBean;
 
 public abstract class AbstractExecutableLogic<T extends EntityTO> extends AbstractJobLogic<T> {
 
+    public AbstractExecutableLogic(final JobManager jobManager, final SchedulerFactoryBean scheduler) {
+        super(jobManager, scheduler);
+    }
+
     public abstract ExecTO execute(String key, Date startAt, boolean dryRun);
 
     public abstract Pair<Integer, List<ExecTO>> listExecutions(
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AbstractJobLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AbstractJobLogic.java
index 5a00435..2adb824 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AbstractJobLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AbstractJobLogic.java
@@ -39,16 +39,18 @@ import org.quartz.SchedulerException;
 import org.quartz.Trigger;
 import org.quartz.impl.matchers.GroupMatcher;
 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.quartz.SchedulerFactoryBean;
 
 abstract class AbstractJobLogic<T extends EntityTO> extends AbstractTransactionalLogic<T> {
 
-    @Autowired
-    protected JobManager jobManager;
+    protected final JobManager jobManager;
 
-    @Autowired
-    protected SchedulerFactoryBean scheduler;
+    protected final SchedulerFactoryBean scheduler;
+
+    protected AbstractJobLogic(final JobManager jobManager, final SchedulerFactoryBean scheduler) {
+        this.jobManager = jobManager;
+        this.scheduler = scheduler;
+    }
 
     protected abstract Triple<JobType, String, String> getReference(JobKey jobKey);
 
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AccessTokenLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AccessTokenLogic.java
index 69b786b..5b978e2 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AccessTokenLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AccessTokenLogic.java
@@ -38,25 +38,13 @@ import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.apache.syncope.core.spring.security.Encryptor;
 import org.apache.syncope.core.spring.security.SecurityProperties;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 
-@Component
 public class AccessTokenLogic extends AbstractTransactionalLogic<AccessTokenTO> {
 
-    private static final Encryptor ENCRYPTOR = Encryptor.getInstance();
+    protected static final Encryptor ENCRYPTOR = Encryptor.getInstance();
 
-    @Autowired
-    private SecurityProperties securityProperties;
-
-    @Autowired
-    private AccessTokenDataBinder binder;
-
-    @Autowired
-    private AccessTokenDAO accessTokenDAO;
-
-    private static byte[] getAuthorities() {
+    protected static byte[] getAuthorities() {
         byte[] authorities = null;
         try {
             authorities = ENCRYPTOR.encode(POJOHelper.serialize(
@@ -69,6 +57,22 @@ public class AccessTokenLogic extends AbstractTransactionalLogic<AccessTokenTO>
         return authorities;
     }
 
+    protected final SecurityProperties securityProperties;
+
+    protected final AccessTokenDataBinder binder;
+
+    protected final AccessTokenDAO accessTokenDAO;
+
+    public AccessTokenLogic(
+            final SecurityProperties securityProperties,
+            final AccessTokenDataBinder binder,
+            final AccessTokenDAO accessTokenDAO) {
+
+        this.securityProperties = securityProperties;
+        this.binder = binder;
+        this.accessTokenDAO = accessTokenDAO;
+    }
+
     @PreAuthorize("isAuthenticated()")
     public Pair<String, Date> login() {
         if (securityProperties.getAnonymousUser().equals(AuthContextUtils.getUsername())) {
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
index e4dc745..54b40a1 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
@@ -41,6 +41,8 @@ import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.PatchOperation;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
@@ -49,29 +51,40 @@ import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
 import org.apache.syncope.core.provisioning.api.LogicActions;
 import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder;
 import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
+import org.apache.syncope.core.provisioning.java.utils.TemplateUtils;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
 /**
  * Note that this controller does not extend {@link AbstractTransactionalLogic}, hence does not provide any
  * Spring's Transactional logic at class level.
  */
-@Component
 public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectCR, AnyObjectUR> {
 
-    @Autowired
-    protected AnyObjectDAO anyObjectDAO;
+    protected final AnyObjectDAO anyObjectDAO;
 
-    @Autowired
-    protected AnySearchDAO searchDAO;
+    protected final AnySearchDAO searchDAO;
 
-    @Autowired
-    protected AnyObjectDataBinder binder;
+    protected final AnyObjectDataBinder binder;
 
-    @Autowired
-    protected AnyObjectProvisioningManager provisioningManager;
+    protected final AnyObjectProvisioningManager provisioningManager;
+
+    public AnyObjectLogic(
+            final RealmDAO realmDAO,
+            final AnyTypeDAO anyTypeDAO,
+            final TemplateUtils templateUtils,
+            final AnyObjectDAO anyObjectDAO,
+            final AnySearchDAO searchDAO,
+            final AnyObjectDataBinder binder,
+            final AnyObjectProvisioningManager provisioningManager) {
+
+        super(realmDAO, anyTypeDAO, templateUtils);
+
+        this.anyObjectDAO = anyObjectDAO;
+        this.searchDAO = searchDAO;
+        this.binder = binder;
+        this.provisioningManager = provisioningManager;
+    }
 
     @Transactional(readOnly = true)
     @Override
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeClassLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeClassLogic.java
index 2cc212f..6cd59ca 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeClassLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeClassLogic.java
@@ -32,19 +32,19 @@ import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
 import org.apache.syncope.core.persistence.api.dao.DuplicateException;
 import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
 import org.apache.syncope.core.provisioning.api.data.AnyTypeClassDataBinder;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class AnyTypeClassLogic extends AbstractTransactionalLogic<AnyTypeClassTO> {
 
-    @Autowired
-    private AnyTypeClassDataBinder binder;
+    protected final AnyTypeClassDataBinder binder;
 
-    @Autowired
-    private AnyTypeClassDAO anyTypeClassDAO;
+    protected final AnyTypeClassDAO anyTypeClassDAO;
+
+    public AnyTypeClassLogic(final AnyTypeClassDataBinder binder, final AnyTypeClassDAO anyTypeClassDAO) {
+        this.binder = binder;
+        this.anyTypeClassDAO = anyTypeClassDAO;
+    }
 
     @PreAuthorize("hasRole('" + IdRepoEntitlement.ANYTYPECLASS_READ + "')")
     @Transactional(readOnly = true)
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
index 1503b42..c414ce9 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
@@ -33,23 +33,27 @@ import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.DuplicateException;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.provisioning.api.data.AnyTypeDataBinder;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.dao.InvalidDataAccessApiUsageException;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class AnyTypeLogic extends AbstractTransactionalLogic<AnyTypeTO> {
 
-    @Autowired
-    private AnyTypeDataBinder binder;
+    protected final AnyTypeDataBinder binder;
 
-    @Autowired
-    private AnyTypeDAO anyTypeDAO;
+    protected final AnyTypeDAO anyTypeDAO;
 
-    @Autowired
-    private AnyObjectDAO anyObjectDAO;
+    protected final AnyObjectDAO anyObjectDAO;
+
+    public AnyTypeLogic(
+            final AnyTypeDataBinder binder,
+            final AnyTypeDAO anyTypeDAO,
+            final AnyObjectDAO anyObjectDAO) {
+
+        this.binder = binder;
+        this.anyTypeDAO = anyTypeDAO;
+        this.anyObjectDAO = anyObjectDAO;
+    }
 
     @PreAuthorize("hasRole('" + IdRepoEntitlement.ANYTYPE_READ + "')")
     @Transactional(readOnly = true)
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ApplicationLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ApplicationLogic.java
index eb558dc..1c6ef4a 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ApplicationLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ApplicationLogic.java
@@ -30,19 +30,19 @@ import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.entity.Application;
 import org.apache.syncope.core.persistence.api.entity.Privilege;
 import org.apache.syncope.core.provisioning.api.data.ApplicationDataBinder;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class ApplicationLogic extends AbstractTransactionalLogic<ApplicationTO> {
 
-    @Autowired
-    private ApplicationDataBinder binder;
+    protected final ApplicationDataBinder binder;
 
-    @Autowired
-    private ApplicationDAO applicationDAO;
+    protected final ApplicationDAO applicationDAO;
+
+    public ApplicationLogic(final ApplicationDataBinder binder, final ApplicationDAO applicationDAO) {
+        this.binder = binder;
+        this.applicationDAO = applicationDAO;
+    }
 
     @PreAuthorize("hasRole('" + IdRepoEntitlement.APPLICATION_READ + "')")
     @Transactional(readOnly = true)
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AuditLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AuditLogic.java
index a57ff6f..8f06029 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AuditLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AuditLogic.java
@@ -54,7 +54,6 @@ import org.apache.syncope.core.provisioning.api.AuditManager;
 import org.apache.syncope.core.provisioning.java.pushpull.PushJobDelegate;
 import org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.io.Resource;
 import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
 import org.springframework.core.io.support.ResourcePatternResolver;
@@ -62,7 +61,6 @@ import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
 import org.springframework.core.type.classreading.MetadataReader;
 import org.springframework.core.type.classreading.MetadataReaderFactory;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.ClassUtils;
 import org.springframework.util.SystemPropertyUtils;
@@ -70,37 +68,48 @@ import org.apache.syncope.core.provisioning.api.data.AuditDataBinder;
 import org.apache.syncope.core.persistence.api.entity.AuditConf;
 import org.apache.syncope.core.persistence.api.dao.AuditConfDAO;
 
-@Component
 public class AuditLogic extends AbstractTransactionalLogic<AuditConfTO> {
 
-    @Autowired
-    private AuditLoader auditLoader;
+    protected static final List<EventCategory> EVENTS = new ArrayList<>();
 
-    @Autowired
-    private AuditConfDAO auditDAO;
+    protected final AuditLoader auditLoader;
 
-    @Autowired
-    private ExternalResourceDAO resourceDAO;
+    protected final AuditConfDAO auditConfDAO;
 
-    @Autowired
-    private EntityFactory entityFactory;
+    protected final ExternalResourceDAO resourceDAO;
 
-    @Autowired
-    private AuditDataBinder binder;
+    protected final EntityFactory entityFactory;
 
-    @Autowired
-    private AuditManager auditManager;
+    protected final AuditDataBinder binder;
+
+    protected final AuditManager auditManager;
+
+    public AuditLogic(
+            final AuditLoader auditLoader,
+            final AuditConfDAO auditConfDAO,
+            final ExternalResourceDAO resourceDAO,
+            final EntityFactory entityFactory,
+            final AuditDataBinder binder,
+            final AuditManager auditManager) {
+
+        this.auditLoader = auditLoader;
+        this.auditConfDAO = auditConfDAO;
+        this.resourceDAO = resourceDAO;
+        this.entityFactory = entityFactory;
+        this.binder = binder;
+        this.auditManager = auditManager;
+    }
 
     @PreAuthorize("hasRole('" + IdRepoEntitlement.AUDIT_LIST + "')")
     @Transactional(readOnly = true)
     public List<AuditConfTO> list() {
-        return auditDAO.findAll().stream().map(binder::getAuditTO).collect(Collectors.toList());
+        return auditConfDAO.findAll().stream().map(binder::getAuditTO).collect(Collectors.toList());
     }
 
     @PreAuthorize("hasRole('" + IdRepoEntitlement.AUDIT_READ + "')")
     @Transactional(readOnly = true)
     public AuditConfTO read(final String key) {
-        return Optional.ofNullable(auditDAO.find(key)).map(binder::getAuditTO).
+        return Optional.ofNullable(auditConfDAO.find(key)).map(binder::getAuditTO).
                 orElseThrow(() -> new NotFoundException("Audit " + key));
     }
 
@@ -109,7 +118,7 @@ public class AuditLogic extends AbstractTransactionalLogic<AuditConfTO> {
         AuditConf audit = entityFactory.newEntity(AuditConf.class);
         audit.setKey(auditTO.getKey());
         audit.setActive(auditTO.isActive());
-        audit = auditDAO.save(audit);
+        audit = auditConfDAO.save(audit);
 
         if (audit.isActive()) {
             setLevel(audit.getKey(), Level.DEBUG);
@@ -118,10 +127,10 @@ public class AuditLogic extends AbstractTransactionalLogic<AuditConfTO> {
 
     @PreAuthorize("hasRole('" + IdRepoEntitlement.AUDIT_UPDATE + "')")
     public void update(final AuditConfTO auditTO) {
-        AuditConf audit = Optional.ofNullable(auditDAO.find(auditTO.getKey())).
+        AuditConf audit = Optional.ofNullable(auditConfDAO.find(auditTO.getKey())).
                 orElseThrow(() -> new NotFoundException("Audit " + auditTO.getKey()));
         audit.setActive(auditTO.isActive());
-        audit = auditDAO.save(audit);
+        audit = auditConfDAO.save(audit);
 
         if (audit.isActive()) {
             setLevel(audit.getKey(), Level.OFF);
@@ -130,14 +139,14 @@ public class AuditLogic extends AbstractTransactionalLogic<AuditConfTO> {
 
     @PreAuthorize("hasRole('" + IdRepoEntitlement.AUDIT_DELETE + "')")
     public void delete(final String key) {
-        AuditConf audit = Optional.ofNullable(auditDAO.find(key)).
+        AuditConf audit = Optional.ofNullable(auditConfDAO.find(key)).
                 orElseThrow(() -> new NotFoundException("Audit " + key));
-        auditDAO.delete(audit);
+        auditConfDAO.delete(audit);
 
         setLevel(audit.getKey(), Level.OFF);
     }
 
-    private void setLevel(final String key, final Level level) {
+    protected void setLevel(final String key, final Level level) {
         String auditLoggerName = AuditLoggerName.getAuditEventLoggerName(AuthContextUtils.getDomain(), key);
 
         LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
@@ -156,6 +165,12 @@ public class AuditLogic extends AbstractTransactionalLogic<AuditConfTO> {
     @PreAuthorize("hasRole('" + IdRepoEntitlement.AUDIT_LIST + "') "
             + "or hasRole('" + IdRepoEntitlement.NOTIFICATION_LIST + "')")
     public List<EventCategory> events() {
+        synchronized (EVENTS) {
+            if (!EVENTS.isEmpty()) {
+                return EVENTS;
+            }
+        }
+
         // use set to avoid duplications or null elements
         Set<EventCategory> events = new HashSet<>();
 
@@ -171,10 +186,10 @@ public class AuditLogic extends AbstractTransactionalLogic<AuditConfTO> {
             Resource[] resources = resourcePatternResolver.getResources(packageSearchPath);
             for (Resource resource : resources) {
                 if (resource.isReadable()) {
-                    final MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource);
-                    final Class<?> clazz = Class.forName(metadataReader.getClassMetadata().getClassName());
+                    MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource);
+                    Class<?> clazz = Class.forName(metadataReader.getClassMetadata().getClassName());
 
-                    if (clazz.isAnnotationPresent(Component.class) && AbstractLogic.class.isAssignableFrom(clazz)) {
+                    if (AbstractLogic.class.isAssignableFrom(clazz)) {
                         EventCategory eventCategory = new EventCategory();
                         eventCategory.setCategory(clazz.getSimpleName());
                         for (Method method : clazz.getDeclaredMethods()) {
@@ -248,7 +263,8 @@ public class AuditLogic extends AbstractTransactionalLogic<AuditConfTO> {
             LOG.error("Failure retrieving audit/notification events", e);
         }
 
-        return new ArrayList<>(events);
+        EVENTS.addAll(events);
+        return EVENTS;
     }
 
     @PreAuthorize("hasRole('" + IdRepoEntitlement.AUDIT_SEARCH + "')")
@@ -264,8 +280,8 @@ public class AuditLogic extends AbstractTransactionalLogic<AuditConfTO> {
             final AuditElements.Result result,
             final List<OrderByClause> orderByClauses) {
 
-        int count = auditDAO.countEntries(entityKey, type, category, subcategory, events, result);
-        List<AuditEntry> matching = auditDAO.searchEntries(
+        int count = auditConfDAO.countEntries(entityKey, type, category, subcategory, events, result);
+        List<AuditEntry> matching = auditConfDAO.searchEntries(
                 entityKey, page, size, type, category, subcategory, events, result, orderByClauses);
         return Pair.of(count, matching);
     }
@@ -312,7 +328,7 @@ public class AuditLogic extends AbstractTransactionalLogic<AuditConfTO> {
 
         if (key != null) {
             try {
-                return binder.getAuditTO(auditDAO.find(key));
+                return binder.getAuditTO(auditConfDAO.find(key));
             } catch (Throwable ignore) {
                 LOG.debug("Unresolved reference", ignore);
                 throw new UnresolvedReferenceException(ignore);
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/DelegationLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/DelegationLogic.java
index bae38b3..f53e85c 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/DelegationLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/DelegationLogic.java
@@ -34,24 +34,28 @@ import org.apache.syncope.core.persistence.api.entity.Delegation;
 import org.apache.syncope.core.provisioning.api.data.DelegationDataBinder;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class DelegationLogic extends AbstractTransactionalLogic<DelegationTO> {
 
-    @Autowired
-    private DelegationDataBinder binder;
+    protected final DelegationDataBinder binder;
 
-    @Autowired
-    private DelegationDAO delegationDAO;
+    protected final DelegationDAO delegationDAO;
 
-    @Autowired
-    private UserDAO userDAO;
+    protected final UserDAO userDAO;
 
-    private void securityChecks(final String delegating, final String entitlement) {
+    public DelegationLogic(
+            final DelegationDataBinder binder,
+            final DelegationDAO delegationDAO,
+            final UserDAO userDAO) {
+
+        this.binder = binder;
+        this.delegationDAO = delegationDAO;
+        this.userDAO = userDAO;
+    }
+
+    protected void securityChecks(final String delegating, final String entitlement) {
         if (!AuthContextUtils.getAuthorizations().keySet().contains(entitlement)
                 && (delegating == null || !delegating.equals(userDAO.findKey(AuthContextUtils.getUsername())))) {
 
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/DynRealmLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/DynRealmLogic.java
index 1cbd1a3..f67023b 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/DynRealmLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/DynRealmLogic.java
@@ -28,19 +28,19 @@ import org.apache.syncope.core.persistence.api.dao.DynRealmDAO;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.entity.DynRealm;
 import org.apache.syncope.core.provisioning.api.data.DynRealmDataBinder;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class DynRealmLogic extends AbstractTransactionalLogic<DynRealmTO> {
 
-    @Autowired
-    private DynRealmDataBinder binder;
+    protected final DynRealmDataBinder binder;
 
-    @Autowired
-    private DynRealmDAO dynRealmDAO;
+    protected final DynRealmDAO dynRealmDAO;
+
+    public DynRealmLogic(final DynRealmDataBinder binder, final DynRealmDAO dynRealmDAO) {
+        this.binder = binder;
+        this.dynRealmDAO = dynRealmDAO;
+    }
 
     @PreAuthorize("hasRole('" + IdRepoEntitlement.DYNREALM_READ + "')")
     @Transactional(readOnly = true)
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
index 357bea8..098b4d2 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
@@ -45,9 +45,11 @@ import org.apache.syncope.common.lib.types.JobType;
 import org.apache.syncope.common.lib.types.PatchOperation;
 import org.apache.syncope.common.lib.types.IdRepoEntitlement;
 import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.ImplementationDAO;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.dao.TaskDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
@@ -65,60 +67,80 @@ import org.apache.syncope.core.provisioning.api.job.JobNamer;
 import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
 import org.apache.syncope.core.provisioning.java.job.GroupMemberProvisionTaskJobDelegate;
 import org.apache.syncope.core.provisioning.java.job.TaskJob;
+import org.apache.syncope.core.provisioning.java.utils.TemplateUtils;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.apache.syncope.core.spring.security.SecurityProperties;
 import org.quartz.JobDataMap;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.quartz.SchedulerFactoryBean;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
 /**
  * Note that this controller does not extend {@link AbstractTransactionalLogic}, hence does not provide any
  * Spring's Transactional logic at class level.
  */
-@Component
 public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupCR, GroupUR> {
 
-    @Autowired
-    protected UserDAO userDAO;
+    protected final UserDAO userDAO;
 
-    @Autowired
-    protected GroupDAO groupDAO;
+    protected final GroupDAO groupDAO;
 
-    @Autowired
-    protected SecurityProperties securityProperties;
+    protected final SecurityProperties securityProperties;
 
-    @Autowired
-    protected AnySearchDAO searchDAO;
+    protected final AnySearchDAO searchDAO;
 
-    @Autowired
-    protected ImplementationDAO implementationDAO;
+    protected final ImplementationDAO implementationDAO;
 
-    @Autowired
-    protected TaskDAO taskDAO;
+    protected final TaskDAO taskDAO;
 
-    @Autowired
-    protected GroupDataBinder binder;
+    protected final GroupDataBinder binder;
 
-    @Autowired
-    protected GroupProvisioningManager provisioningManager;
+    protected final GroupProvisioningManager provisioningManager;
 
-    @Autowired
-    protected TaskDataBinder taskDataBinder;
+    protected final TaskDataBinder taskDataBinder;
 
-    @Autowired
-    protected ConfParamOps confParamOps;
+    protected final ConfParamOps confParamOps;
 
-    @Autowired
-    protected JobManager jobManager;
+    protected final JobManager jobManager;
 
-    @Autowired
-    protected SchedulerFactoryBean scheduler;
+    protected final SchedulerFactoryBean scheduler;
 
-    @Autowired
-    protected EntityFactory entityFactory;
+    protected final EntityFactory entityFactory;
+
+    public GroupLogic(
+            final RealmDAO realmDAO,
+            final AnyTypeDAO anyTypeDAO,
+            final TemplateUtils templateUtils,
+            final UserDAO userDAO,
+            final GroupDAO groupDAO,
+            final SecurityProperties securityProperties,
+            final AnySearchDAO searchDAO,
+            final ImplementationDAO implementationDAO,
+            final TaskDAO taskDAO,
+            final GroupDataBinder binder,
+            final GroupProvisioningManager provisioningManager,
+            final TaskDataBinder taskDataBinder,
+            final ConfParamOps confParamOps,
+            final JobManager jobManager,
+            final SchedulerFactoryBean scheduler,
+            final EntityFactory entityFactory) {
+
+        super(realmDAO, anyTypeDAO, templateUtils);
+
+        this.userDAO = userDAO;
+        this.groupDAO = groupDAO;
+        this.securityProperties = securityProperties;
+        this.searchDAO = searchDAO;
+        this.implementationDAO = implementationDAO;
+        this.taskDAO = taskDAO;
+        this.binder = binder;
+        this.provisioningManager = provisioningManager;
+        this.taskDataBinder = taskDataBinder;
+        this.confParamOps = confParamOps;
+        this.jobManager = jobManager;
+        this.scheduler = scheduler;
+        this.entityFactory = entityFactory;
+    }
 
     @PreAuthorize("hasRole('" + IdRepoEntitlement.GROUP_READ + "')")
     @Transactional(readOnly = true)
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/IdRepoLogicContext.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/IdRepoLogicContext.java
new file mode 100644
index 0000000..0b2ac07
--- /dev/null
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/IdRepoLogicContext.java
@@ -0,0 +1,515 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.logic;
+
+import org.apache.syncope.common.keymaster.client.api.ConfParamOps;
+import org.apache.syncope.core.logic.init.AuditAccessor;
+import org.apache.syncope.core.logic.init.AuditLoader;
+import org.apache.syncope.core.logic.init.ClassPathScanImplementationLookup;
+import org.apache.syncope.core.logic.init.EntitlementAccessor;
+import org.apache.syncope.core.logic.init.IdRepoEntitlementLoader;
+import org.apache.syncope.core.logic.init.IdRepoImplementationTypeLoader;
+import org.apache.syncope.core.persistence.api.ImplementationLookup;
+import org.apache.syncope.core.persistence.api.content.ContentExporter;
+import org.apache.syncope.core.persistence.api.dao.AccessTokenDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.ApplicationDAO;
+import org.apache.syncope.core.persistence.api.dao.AuditConfDAO;
+import org.apache.syncope.core.persistence.api.dao.DelegationDAO;
+import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.DynRealmDAO;
+import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.ImplementationDAO;
+import org.apache.syncope.core.persistence.api.dao.MailTemplateDAO;
+import org.apache.syncope.core.persistence.api.dao.NotificationDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.dao.RelationshipTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.ReportDAO;
+import org.apache.syncope.core.persistence.api.dao.ReportExecDAO;
+import org.apache.syncope.core.persistence.api.dao.ReportTemplateDAO;
+import org.apache.syncope.core.persistence.api.dao.RoleDAO;
+import org.apache.syncope.core.persistence.api.dao.SecurityQuestionDAO;
+import org.apache.syncope.core.persistence.api.dao.TaskDAO;
+import org.apache.syncope.core.persistence.api.dao.TaskExecDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.policy.PolicyUtilsFactory;
+import org.apache.syncope.core.persistence.api.entity.task.TaskUtilsFactory;
+import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
+import org.apache.syncope.core.provisioning.api.AuditManager;
+import org.apache.syncope.core.provisioning.api.GroupProvisioningManager;
+import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
+import org.apache.syncope.core.provisioning.api.data.AccessTokenDataBinder;
+import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder;
+import org.apache.syncope.core.provisioning.api.data.AnyTypeClassDataBinder;
+import org.apache.syncope.core.provisioning.api.data.AnyTypeDataBinder;
+import org.apache.syncope.core.provisioning.api.data.ApplicationDataBinder;
+import org.apache.syncope.core.provisioning.api.data.AuditDataBinder;
+import org.apache.syncope.core.provisioning.api.data.DelegationDataBinder;
+import org.apache.syncope.core.provisioning.api.data.DynRealmDataBinder;
+import org.apache.syncope.core.provisioning.api.data.GroupDataBinder;
+import org.apache.syncope.core.provisioning.api.data.ImplementationDataBinder;
+import org.apache.syncope.core.provisioning.api.data.NotificationDataBinder;
+import org.apache.syncope.core.provisioning.api.data.PolicyDataBinder;
+import org.apache.syncope.core.provisioning.api.data.RealmDataBinder;
+import org.apache.syncope.core.provisioning.api.data.RelationshipTypeDataBinder;
+import org.apache.syncope.core.provisioning.api.data.ReportDataBinder;
+import org.apache.syncope.core.provisioning.api.data.RoleDataBinder;
+import org.apache.syncope.core.provisioning.api.data.SchemaDataBinder;
+import org.apache.syncope.core.provisioning.api.data.SecurityQuestionDataBinder;
+import org.apache.syncope.core.provisioning.api.data.TaskDataBinder;
+import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
+import org.apache.syncope.core.provisioning.api.job.JobManager;
+import org.apache.syncope.core.provisioning.api.notification.NotificationJobDelegate;
+import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
+import org.apache.syncope.core.provisioning.java.utils.TemplateUtils;
+import org.apache.syncope.core.spring.security.SecurityProperties;
+import org.apache.syncope.core.workflow.api.AnyObjectWorkflowAdapter;
+import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
+import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
+import org.springframework.scheduling.quartz.SchedulerFactoryBean;
+
+@EnableAspectJAutoProxy
+@EnableConfigurationProperties(LogicProperties.class)
+@Configuration
+public class IdRepoLogicContext {
+
+    @Autowired
+    private LogicProperties logicProperties;
+
+    @Autowired
+    private SecurityProperties securityProperties;
+
+    @Autowired
+    private AccessTokenDAO accessTokenDAO;
+
+    @Autowired
+    private AnySearchDAO anySearchDAO;
+
+    @Autowired
+    private AnyObjectDAO anyObjectDAO;
+
+    @Autowired
+    private AnyTypeClassDAO anyTypeClassDAO;
+
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
+    private AuditConfDAO auditConfDAO;
+
+    @Autowired
+    private DelegationDAO delegationDAO;
+
+    @Autowired
+    private DerSchemaDAO derSchemaDAO;
+
+    @Autowired
+    private ExternalResourceDAO externalResourceDAO;
+
+    @Autowired
+    private GroupDAO groupDAO;
+
+    @Autowired
+    private ImplementationDAO implementationDAO;
+
+    @Autowired
+    private NotificationDAO notificationDAO;
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Autowired
+    private PolicyDAO policyDAO;
+
+    @Autowired
+    private RealmDAO realmDAO;
+
+    @Autowired
+    private ReportDAO reportDAO;
+
+    @Autowired
+    private TaskDAO taskDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private VirSchemaDAO virSchemaDAO;
+
+    @Autowired
+    private AuditManager auditManager;
+
+    @Autowired
+    private TemplateUtils templateUtils;
+
+    @Autowired
+    private EntityFactory entityFactory;
+
+    @Autowired
+    private GroupDataBinder groupDataBinder;
+
+    @Autowired
+    private TaskDataBinder taskDataBinder;
+
+    @Autowired
+    private ConfParamOps confParamOps;
+
+    @Autowired
+    private JobManager jobManager;
+
+    @Autowired
+    private SchedulerFactoryBean scheduler;
+
+    @Autowired
+    private PropagationManager propagationManager;
+
+    @Autowired
+    private PropagationTaskExecutor taskExecutor;
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public LogicInvocationHandler logicInvocationHandler(final NotificationManager notificationManager) {
+        return new LogicInvocationHandler(notificationManager, auditManager);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public ImplementationLookup implementationLookup() {
+        return new ClassPathScanImplementationLookup();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public AuditAccessor auditAccessor() {
+        return new AuditAccessor(auditConfDAO);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public AuditLoader auditLoader(final AuditAccessor auditAccessor, final ImplementationLookup implementationLookup) {
+        return new AuditLoader(auditAccessor, implementationLookup, logicProperties);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public EntitlementAccessor entitlementAccessor() {
+        return new EntitlementAccessor(anyTypeDAO);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public IdRepoEntitlementLoader idRepoEntitlementLoader() {
+        return new IdRepoEntitlementLoader(entitlementAccessor());
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public IdRepoImplementationTypeLoader idRepoImplementationTypeLoader() {
+        return new IdRepoImplementationTypeLoader();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public AccessTokenLogic accessTokenLogic(final AccessTokenDataBinder binder) {
+        return new AccessTokenLogic(securityProperties, binder, accessTokenDAO);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public AnyObjectLogic anyObjectLogic(
+            final AnyObjectDataBinder binder,
+            final AnyObjectProvisioningManager provisioningManager) {
+
+        return new AnyObjectLogic(
+                realmDAO,
+                anyTypeDAO,
+                templateUtils,
+                anyObjectDAO,
+                anySearchDAO,
+                binder,
+                provisioningManager);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public AnyTypeClassLogic anyTypeClassLogic(final AnyTypeClassDataBinder binder) {
+        return new AnyTypeClassLogic(binder, anyTypeClassDAO);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public AnyTypeLogic anyTypeLogic(final AnyTypeDataBinder binder) {
+        return new AnyTypeLogic(binder, anyTypeDAO, anyObjectDAO);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public ApplicationLogic applicationLogic(
+            final ApplicationDataBinder binder,
+            final ApplicationDAO applicationDAO) {
+
+        return new ApplicationLogic(binder, applicationDAO);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public AuditLogic auditLogic(
+            final AuditLoader auditLoader,
+            final AuditDataBinder binder) {
+
+        return new AuditLogic(
+                auditLoader,
+                auditConfDAO,
+                externalResourceDAO,
+                entityFactory,
+                binder,
+                auditManager);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public DelegationLogic delegationLogic(final DelegationDataBinder binder) {
+        return new DelegationLogic(binder, delegationDAO, userDAO);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public DynRealmLogic dynRealmLogic(
+            final DynRealmDataBinder binder,
+            final DynRealmDAO dynRealmDAO) {
+
+        return new DynRealmLogic(binder, dynRealmDAO);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public GroupLogic groupLogic(final GroupProvisioningManager provisioningManager) {
+        return new GroupLogic(
+                realmDAO,
+                anyTypeDAO,
+                templateUtils,
+                userDAO,
+                groupDAO,
+                securityProperties,
+                anySearchDAO,
+                implementationDAO,
+                taskDAO,
+                groupDataBinder,
+                provisioningManager,
+                taskDataBinder,
+                confParamOps,
+                jobManager,
+                scheduler,
+                entityFactory);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public ImplementationLogic implementationLogic(final ImplementationDataBinder binder) {
+        return new ImplementationLogic(
+                binder,
+                implementationDAO,
+                reportDAO,
+                policyDAO,
+                externalResourceDAO,
+                taskDAO,
+                realmDAO,
+                plainSchemaDAO,
+                notificationDAO);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public MailTemplateLogic mailTemplateLogic(final MailTemplateDAO mailTemplateDAO) {
+        return new MailTemplateLogic(mailTemplateDAO, notificationDAO, entityFactory);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public NotificationLogic notificationLogic(final NotificationDataBinder binder) {
+        return new NotificationLogic(jobManager, scheduler, notificationDAO, binder);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public PolicyLogic policyLogic(
+            final PolicyDataBinder binder,
+            final PolicyUtilsFactory policyUtilsFactory) {
+
+        return new PolicyLogic(policyDAO, binder, policyUtilsFactory);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public RealmLogic realmLogic(final RealmDataBinder binder) {
+        return new RealmLogic(realmDAO, anySearchDAO, binder, propagationManager, taskExecutor);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public RelationshipTypeLogic relationshipTypeLogic(
+            final RelationshipTypeDataBinder binder,
+            final RelationshipTypeDAO relationshipTypeDAO) {
+
+        return new RelationshipTypeLogic(binder, relationshipTypeDAO);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public ReportLogic reportLogic(
+            final ReportDataBinder binder,
+            final ReportExecDAO reportExecDAO) {
+
+        return new ReportLogic(jobManager, scheduler, reportDAO, reportExecDAO, confParamOps, binder, entityFactory);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public ReportTemplateLogic reportTemplateLogic(final ReportTemplateDAO reportTemplateDAO) {
+        return new ReportTemplateLogic(reportTemplateDAO, reportDAO, entityFactory);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public RoleLogic roleLogic(
+            final RoleDataBinder binder,
+            final RoleDAO roleDAO) {
+
+        return new RoleLogic(binder, roleDAO);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public SchemaLogic schemaLogic(final SchemaDataBinder binder) {
+        return new SchemaLogic(plainSchemaDAO, derSchemaDAO, virSchemaDAO, anyTypeClassDAO, binder);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public SecurityQuestionLogic securityQuestionLogic(
+            final SecurityQuestionDataBinder binder,
+            final SecurityQuestionDAO securityQuestionDAO) {
+
+        return new SecurityQuestionLogic(securityQuestionDAO, userDAO, binder);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public SyncopeLogic syncopeLogic(
+            final ContentExporter exporter,
+            final UserWorkflowAdapter uwfAdapter,
+            final GroupWorkflowAdapter gwfAdapter,
+            final AnyObjectWorkflowAdapter awfAdapter) {
+
+        return new SyncopeLogic(
+                anyTypeDAO,
+                groupDAO,
+                anySearchDAO,
+                groupDataBinder,
+                confParamOps,
+                exporter,
+                uwfAdapter,
+                gwfAdapter,
+                awfAdapter);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public TaskLogic taskLogic(
+            final TaskExecDAO taskExecDAO,
+            final NotificationJobDelegate notificationJobDelegate,
+            final TaskUtilsFactory taskUtilsFactory) {
+
+        return new TaskLogic(
+                jobManager,
+                scheduler,
+                taskDAO,
+                taskExecDAO,
+                externalResourceDAO,
+                notificationDAO,
+                confParamOps,
+                taskDataBinder,
+                taskExecutor,
+                notificationJobDelegate,
+                taskUtilsFactory);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public UserLogic userLogic(
+            final UserDataBinder binder,
+            final UserProvisioningManager provisioningManager,
+            final SyncopeLogic syncopeLogic) {
+
+        return new UserLogic(
+                realmDAO,
+                anyTypeDAO,
+                templateUtils,
+                userDAO,
+                groupDAO,
+                anySearchDAO,
+                accessTokenDAO,
+                delegationDAO,
+                confParamOps,
+                binder,
+                provisioningManager,
+                syncopeLogic);
+    }
+}
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ImplementationLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ImplementationLogic.java
index a2fd3d9..829bea4 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ImplementationLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ImplementationLogic.java
@@ -42,42 +42,52 @@ import org.apache.syncope.core.persistence.api.dao.ReportDAO;
 import org.apache.syncope.core.persistence.api.dao.TaskDAO;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.apache.syncope.core.provisioning.api.data.ImplementationDataBinder;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class ImplementationLogic extends AbstractTransactionalLogic<ImplementationTO> {
 
-    @Autowired
-    private ImplementationDataBinder binder;
+    protected final ImplementationDataBinder binder;
 
-    @Autowired
-    private ImplementationDAO implementationDAO;
+    protected final ImplementationDAO implementationDAO;
 
-    @Autowired
-    private ReportDAO reportDAO;
+    protected final ReportDAO reportDAO;
 
-    @Autowired
-    private PolicyDAO policyDAO;
+    protected final PolicyDAO policyDAO;
 
-    @Autowired
-    private ExternalResourceDAO resourceDAO;
+    protected final ExternalResourceDAO resourceDAO;
 
-    @Autowired
-    private TaskDAO taskDAO;
+    protected final TaskDAO taskDAO;
 
-    @Autowired
-    private RealmDAO realmDAO;
+    protected final RealmDAO realmDAO;
 
-    @Autowired
-    private PlainSchemaDAO plainSchemaDAO;
+    protected final PlainSchemaDAO plainSchemaDAO;
 
-    @Autowired
-    private NotificationDAO notificationDAO;
+    protected final NotificationDAO notificationDAO;
 
-    private static void checkType(final String type) {
+    public ImplementationLogic(
+            final ImplementationDataBinder binder,
+            final ImplementationDAO implementationDAO,
+            final ReportDAO reportDAO,
+            final PolicyDAO policyDAO,
+            final ExternalResourceDAO resourceDAO,
+            final TaskDAO taskDAO,
+            final RealmDAO realmDAO,
+            final PlainSchemaDAO plainSchemaDAO,
+            final NotificationDAO notificationDAO) {
+
+        this.binder = binder;
+        this.implementationDAO = implementationDAO;
+        this.reportDAO = reportDAO;
+        this.policyDAO = policyDAO;
+        this.resourceDAO = resourceDAO;
+        this.taskDAO = taskDAO;
+        this.realmDAO = realmDAO;
+        this.plainSchemaDAO = plainSchemaDAO;
+        this.notificationDAO = notificationDAO;
+    }
+
+    protected void checkType(final String type) {
         if (!ImplementationTypesHolder.getInstance().getValues().containsKey(type)) {
             SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidImplementationType);
             sce.getElements().add("Implementation type not found: ");
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/LogicInvocationHandler.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/LogicInvocationHandler.java
index 675f4d3..77d3c84 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/LogicInvocationHandler.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/LogicInvocationHandler.java
@@ -31,18 +31,20 @@ import org.aspectj.lang.annotation.Aspect;
 import org.aspectj.lang.reflect.MethodSignature;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
 
 @Aspect
 public class LogicInvocationHandler {
 
-    private static final Logger LOG = LoggerFactory.getLogger(LogicInvocationHandler.class);
+    protected static final Logger LOG = LoggerFactory.getLogger(LogicInvocationHandler.class);
 
-    @Autowired
-    private NotificationManager notificationManager;
+    protected final NotificationManager notificationManager;
 
-    @Autowired
-    private AuditManager auditManager;
+    protected final AuditManager auditManager;
+
+    public LogicInvocationHandler(final NotificationManager notificationManager, final AuditManager auditManager) {
+        this.notificationManager = notificationManager;
+        this.auditManager = auditManager;
+    }
 
     @Around("execution(* org.apache.syncope.core.logic.AbstractLogic+.*(..))")
     public Object around(final ProceedingJoinPoint joinPoint) throws Throwable {
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/LogicProperties.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/LogicProperties.java
index 6c84fcf..0b69910 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/LogicProperties.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/LogicProperties.java
@@ -18,35 +18,13 @@
  */
 package org.apache.syncope.core.logic;
 
-import org.apache.syncope.core.logic.init.ClassPathScanImplementationLookup;
-import org.apache.syncope.core.persistence.api.ImplementationLookup;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 
 @ConfigurationProperties("logic")
 public class LogicProperties {
 
-    private Class<? extends LogicInvocationHandler> invocationHandler = LogicInvocationHandler.class;
-
-    private Class<? extends ImplementationLookup> implementationLookup = ClassPathScanImplementationLookup.class;
-
     private boolean enableJDBCAuditAppender = true;
 
-    public Class<? extends LogicInvocationHandler> getInvocationHandler() {
-        return invocationHandler;
-    }
-
-    public void setInvocationHandler(final Class<? extends LogicInvocationHandler> invocationHandler) {
-        this.invocationHandler = invocationHandler;
-    }
-
-    public Class<? extends ImplementationLookup> getImplementationLookup() {
-        return implementationLookup;
-    }
-
-    public void setImplementationLookup(final Class<? extends ImplementationLookup> implementationLookup) {
-        this.implementationLookup = implementationLookup;
-    }
-
     public boolean isEnableJDBCAuditAppender() {
         return enableJDBCAuditAppender;
     }
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/MailTemplateLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/MailTemplateLogic.java
index 074a2bd..d53c539 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/MailTemplateLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/MailTemplateLogic.java
@@ -36,24 +36,28 @@ import org.apache.syncope.core.persistence.api.entity.Entity;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.MailTemplate;
 import org.apache.syncope.core.persistence.api.entity.Notification;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class MailTemplateLogic extends AbstractTransactionalLogic<MailTemplateTO> {
 
-    @Autowired
-    private MailTemplateDAO mailTemplateDAO;
+    protected final MailTemplateDAO mailTemplateDAO;
 
-    @Autowired
-    private NotificationDAO notificationDAO;
+    protected final NotificationDAO notificationDAO;
 
-    @Autowired
-    private EntityFactory entityFactory;
+    protected final EntityFactory entityFactory;
 
-    private static MailTemplateTO getMailTemplateTO(final String key) {
+    public MailTemplateLogic(
+            final MailTemplateDAO mailTemplateDAO,
+            final NotificationDAO notificationDAO,
+            final EntityFactory entityFactory) {
+
+        this.mailTemplateDAO = mailTemplateDAO;
+        this.notificationDAO = notificationDAO;
+        this.entityFactory = entityFactory;
+    }
+
+    protected MailTemplateTO getMailTemplateTO(final String key) {
         MailTemplateTO mailTemplateTO = new MailTemplateTO();
         mailTemplateTO.setKey(key);
         return mailTemplateTO;
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/NotificationLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/NotificationLogic.java
index af54d4b..f43758e 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/NotificationLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/NotificationLogic.java
@@ -35,19 +35,27 @@ import org.apache.syncope.core.provisioning.api.data.NotificationDataBinder;
 import org.apache.syncope.core.provisioning.api.job.JobManager;
 import org.apache.syncope.core.provisioning.java.job.notification.NotificationJob;
 import org.quartz.JobKey;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.quartz.SchedulerFactoryBean;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class NotificationLogic extends AbstractJobLogic<NotificationTO> {
 
-    @Autowired
-    private NotificationDAO notificationDAO;
+    protected final NotificationDAO notificationDAO;
 
-    @Autowired
-    private NotificationDataBinder binder;
+    protected final NotificationDataBinder binder;
+
+    public NotificationLogic(
+            final JobManager jobManager,
+            final SchedulerFactoryBean scheduler,
+            final NotificationDAO notificationDAO,
+            final NotificationDataBinder binder) {
+
+        super(jobManager, scheduler);
+
+        this.notificationDAO = notificationDAO;
+        this.binder = binder;
+    }
 
     @PreAuthorize("hasRole('" + IdRepoEntitlement.NOTIFICATION_READ + "')")
     @Transactional(readOnly = true)
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/PolicyLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/PolicyLogic.java
index d391d71..681b58e 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/PolicyLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/PolicyLogic.java
@@ -33,22 +33,26 @@ import org.apache.syncope.core.persistence.api.entity.policy.Policy;
 import org.apache.syncope.core.persistence.api.entity.policy.PolicyUtils;
 import org.apache.syncope.core.persistence.api.entity.policy.PolicyUtilsFactory;
 import org.apache.syncope.core.provisioning.api.data.PolicyDataBinder;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class PolicyLogic extends AbstractTransactionalLogic<PolicyTO> {
 
-    @Autowired
-    private PolicyDAO policyDAO;
+    protected final PolicyDAO policyDAO;
 
-    @Autowired
-    private PolicyDataBinder binder;
+    protected final PolicyDataBinder binder;
 
-    @Autowired
-    private PolicyUtilsFactory policyUtilsFactory;
+    protected final PolicyUtilsFactory policyUtilsFactory;
+
+    public PolicyLogic(
+            final PolicyDAO policyDAO,
+            final PolicyDataBinder binder,
+            final PolicyUtilsFactory policyUtilsFactory) {
+
+        this.policyDAO = policyDAO;
+        this.binder = binder;
+        this.policyUtilsFactory = policyUtilsFactory;
+    }
 
     @PreAuthorize("hasRole('" + IdRepoEntitlement.POLICY_CREATE + "')")
     public <T extends PolicyTO> T create(final PolicyType type, final T policyTO) {
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RealmLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RealmLogic.java
index 6db99ec..bd1a0a9 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RealmLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RealmLogic.java
@@ -48,28 +48,34 @@ import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskInfo;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class RealmLogic extends AbstractTransactionalLogic<RealmTO> {
 
-    @Autowired
-    private RealmDAO realmDAO;
+    protected final RealmDAO realmDAO;
 
-    @Autowired
-    private AnySearchDAO searchDAO;
+    protected final AnySearchDAO searchDAO;
 
-    @Autowired
-    private RealmDataBinder binder;
+    protected final RealmDataBinder binder;
 
-    @Autowired
-    private PropagationManager propagationManager;
+    protected final PropagationManager propagationManager;
 
-    @Autowired
-    private PropagationTaskExecutor taskExecutor;
+    protected final PropagationTaskExecutor taskExecutor;
+
+    public RealmLogic(
+            final RealmDAO realmDAO,
+            final AnySearchDAO searchDAO,
+            final RealmDataBinder binder,
+            final PropagationManager propagationManager,
+            final PropagationTaskExecutor taskExecutor) {
+
+        this.realmDAO = realmDAO;
+        this.searchDAO = searchDAO;
+        this.binder = binder;
+        this.propagationManager = propagationManager;
+        this.taskExecutor = taskExecutor;
+    }
 
     @PreAuthorize("hasRole('" + IdRepoEntitlement.REALM_LIST + "')")
     @Transactional(readOnly = true)
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RelationshipTypeLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RelationshipTypeLogic.java
index 1b76d42..998bfe7 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RelationshipTypeLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RelationshipTypeLogic.java
@@ -29,19 +29,22 @@ import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.RelationshipTypeDAO;
 import org.apache.syncope.core.persistence.api.entity.RelationshipType;
 import org.apache.syncope.core.provisioning.api.data.RelationshipTypeDataBinder;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class RelationshipTypeLogic extends AbstractTransactionalLogic<RelationshipTypeTO> {
 
-    @Autowired
-    private RelationshipTypeDataBinder binder;
+    protected final RelationshipTypeDataBinder binder;
 
-    @Autowired
-    private RelationshipTypeDAO relationshipTypeDAO;
+    protected final RelationshipTypeDAO relationshipTypeDAO;
+
+    public RelationshipTypeLogic(
+            final RelationshipTypeDataBinder binder,
+            final RelationshipTypeDAO relationshipTypeDAO) {
+
+        this.binder = binder;
+        this.relationshipTypeDAO = relationshipTypeDAO;
+    }
 
     @PreAuthorize("hasRole('" + IdRepoEntitlement.RELATIONSHIPTYPE_READ + "')")
     @Transactional(readOnly = true)
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ReportLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ReportLogic.java
index bf5b987..75aa53c 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ReportLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ReportLogic.java
@@ -65,34 +65,46 @@ import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.Report;
 import org.apache.syncope.core.persistence.api.entity.ReportExec;
 import org.apache.syncope.core.provisioning.api.data.ReportDataBinder;
+import org.apache.syncope.core.provisioning.api.job.JobManager;
 import org.apache.syncope.core.provisioning.api.job.JobNamer;
 import org.apache.syncope.core.provisioning.api.utils.ExceptionUtils2;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.apache.xmlgraphics.util.MimeConstants;
 import org.quartz.JobKey;
 import org.quartz.SchedulerException;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.quartz.SchedulerFactoryBean;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class ReportLogic extends AbstractExecutableLogic<ReportTO> {
 
-    @Autowired
-    private ReportDAO reportDAO;
+    protected final ReportDAO reportDAO;
 
-    @Autowired
-    private ReportExecDAO reportExecDAO;
+    protected final ReportExecDAO reportExecDAO;
 
-    @Autowired
-    private ConfParamOps confParamOps;
+    protected final ConfParamOps confParamOps;
 
-    @Autowired
-    private ReportDataBinder binder;
+    protected final ReportDataBinder binder;
 
-    @Autowired
-    private EntityFactory entityFactory;
+    protected final EntityFactory entityFactory;
+
+    public ReportLogic(
+            final JobManager jobManager,
+            final SchedulerFactoryBean scheduler,
+            final ReportDAO reportDAO,
+            final ReportExecDAO reportExecDAO,
+            final ConfParamOps confParamOps,
+            final ReportDataBinder binder,
+            final EntityFactory entityFactory) {
+
+        super(jobManager, scheduler);
+
+        this.reportDAO = reportDAO;
+        this.reportExecDAO = reportExecDAO;
+        this.confParamOps = confParamOps;
+        this.binder = binder;
+        this.entityFactory = entityFactory;
+    }
 
     @PreAuthorize("hasRole('" + IdRepoEntitlement.REPORT_CREATE + "')")
     public ReportTO create(final ReportTO reportTO) {
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ReportTemplateLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ReportTemplateLogic.java
index 907a7b9..4735c03 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ReportTemplateLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ReportTemplateLogic.java
@@ -36,24 +36,28 @@ import org.apache.syncope.core.persistence.api.entity.Entity;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.ReportTemplate;
 import org.apache.syncope.core.persistence.api.entity.Report;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class ReportTemplateLogic extends AbstractTransactionalLogic<ReportTemplateTO> {
 
-    @Autowired
-    private ReportTemplateDAO reportTemplateDAO;
+    protected final ReportTemplateDAO reportTemplateDAO;
 
-    @Autowired
-    private ReportDAO reportDAO;
+    protected final ReportDAO reportDAO;
 
-    @Autowired
-    private EntityFactory entityFactory;
+    protected final EntityFactory entityFactory;
 
-    private static ReportTemplateTO getReportTemplateTO(final String key) {
+    public ReportTemplateLogic(
+            final ReportTemplateDAO reportTemplateDAO,
+            final ReportDAO reportDAO,
+            final EntityFactory entityFactory) {
+
+        this.reportTemplateDAO = reportTemplateDAO;
+        this.reportDAO = reportDAO;
+        this.entityFactory = entityFactory;
+    }
+
+    protected ReportTemplateTO getReportTemplateTO(final String key) {
         ReportTemplateTO reportTemplateTO = new ReportTemplateTO();
         reportTemplateTO.setKey(key);
         return reportTemplateTO;
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RoleLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RoleLogic.java
index 5a09253..e6e788c 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RoleLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RoleLogic.java
@@ -32,19 +32,19 @@ import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.RoleDAO;
 import org.apache.syncope.core.persistence.api.entity.Role;
 import org.apache.syncope.core.provisioning.api.data.RoleDataBinder;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class RoleLogic extends AbstractTransactionalLogic<RoleTO> {
 
-    @Autowired
-    private RoleDataBinder binder;
+    protected final RoleDataBinder binder;
 
-    @Autowired
-    private RoleDAO roleDAO;
+    protected final RoleDAO roleDAO;
+
+    public RoleLogic(final RoleDataBinder binder, final RoleDAO roleDAO) {
+        this.binder = binder;
+        this.roleDAO = roleDAO;
+    }
 
     @PreAuthorize("hasRole('" + IdRepoEntitlement.ROLE_READ + "')")
     @Transactional(readOnly = true)
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java
index 1e08b6e..3c110bd 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java
@@ -45,30 +45,36 @@ import org.apache.syncope.core.persistence.api.entity.DerSchema;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.provisioning.api.data.SchemaDataBinder;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class SchemaLogic extends AbstractTransactionalLogic<SchemaTO> {
 
-    @Autowired
-    private PlainSchemaDAO plainSchemaDAO;
+    protected final PlainSchemaDAO plainSchemaDAO;
 
-    @Autowired
-    private DerSchemaDAO derSchemaDAO;
+    protected final DerSchemaDAO derSchemaDAO;
 
-    @Autowired
-    private VirSchemaDAO virSchemaDAO;
+    protected final VirSchemaDAO virSchemaDAO;
 
-    @Autowired
-    private AnyTypeClassDAO anyTypeClassDAO;
+    protected final AnyTypeClassDAO anyTypeClassDAO;
 
-    @Autowired
-    private SchemaDataBinder binder;
+    protected final SchemaDataBinder binder;
 
-    private boolean doesSchemaExist(final SchemaType schemaType, final String name) {
+    public SchemaLogic(
+            final PlainSchemaDAO plainSchemaDAO,
+            final DerSchemaDAO derSchemaDAO,
+            final VirSchemaDAO virSchemaDAO,
+            final AnyTypeClassDAO anyTypeClassDAO,
+            final SchemaDataBinder binder) {
+
+        this.plainSchemaDAO = plainSchemaDAO;
+        this.derSchemaDAO = derSchemaDAO;
+        this.virSchemaDAO = virSchemaDAO;
+        this.anyTypeClassDAO = anyTypeClassDAO;
+        this.binder = binder;
+    }
+
+    protected boolean doesSchemaExist(final SchemaType schemaType, final String name) {
         boolean found;
 
         switch (schemaType) {
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/SecurityQuestionLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/SecurityQuestionLogic.java
index 20610a8..cf1c20b 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/SecurityQuestionLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/SecurityQuestionLogic.java
@@ -30,22 +30,26 @@ import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.entity.user.SecurityQuestion;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.data.SecurityQuestionDataBinder;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class SecurityQuestionLogic extends AbstractTransactionalLogic<SecurityQuestionTO> {
 
-    @Autowired
-    private SecurityQuestionDAO securityQuestionDAO;
+    protected final SecurityQuestionDAO securityQuestionDAO;
 
-    @Autowired
-    private UserDAO userDAO;
+    protected final UserDAO userDAO;
 
-    @Autowired
-    private SecurityQuestionDataBinder binder;
+    protected final SecurityQuestionDataBinder binder;
+
+    public SecurityQuestionLogic(
+            final SecurityQuestionDAO securityQuestionDAO,
+            final UserDAO userDAO,
+            final SecurityQuestionDataBinder binder) {
+
+        this.securityQuestionDAO = securityQuestionDAO;
+        this.userDAO = userDAO;
+        this.binder = binder;
+    }
 
     @PreAuthorize("isAuthenticated()")
     @Transactional(readOnly = true)
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
index 8a9b8bc..b90aefd 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
@@ -49,41 +49,51 @@ import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.apache.syncope.core.workflow.api.AnyObjectWorkflowAdapter;
 import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
 import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
 @Transactional(readOnly = true)
-@Component
 public class SyncopeLogic extends AbstractLogic<EntityTO> {
 
-    @Autowired
-    private AnyTypeDAO anyTypeDAO;
+    protected final AnyTypeDAO anyTypeDAO;
 
-    @Autowired
-    private GroupDAO groupDAO;
+    protected final GroupDAO groupDAO;
 
-    @Autowired
-    private AnySearchDAO searchDAO;
+    protected final AnySearchDAO searchDAO;
 
-    @Autowired
-    private GroupDataBinder groupDataBinder;
+    protected final GroupDataBinder groupDataBinder;
 
-    @Autowired
-    private ConfParamOps confParamOps;
+    protected final ConfParamOps confParamOps;
 
-    @Autowired
-    private AnyObjectWorkflowAdapter awfAdapter;
+    protected final ContentExporter exporter;
 
-    @Autowired
-    private ContentExporter exporter;
+    protected final UserWorkflowAdapter uwfAdapter;
 
-    @Autowired
-    private UserWorkflowAdapter uwfAdapter;
+    protected final GroupWorkflowAdapter gwfAdapter;
 
-    @Autowired
-    private GroupWorkflowAdapter gwfAdapter;
+    protected final AnyObjectWorkflowAdapter awfAdapter;
+
+    public SyncopeLogic(
+            final AnyTypeDAO anyTypeDAO,
+            final GroupDAO groupDAO,
+            final AnySearchDAO searchDAO,
+            final GroupDataBinder groupDataBinder,
+            final ConfParamOps confParamOps,
+            final ContentExporter exporter,
+            final UserWorkflowAdapter uwfAdapter,
+            final GroupWorkflowAdapter gwfAdapter,
+            final AnyObjectWorkflowAdapter awfAdapter) {
+
+        this.anyTypeDAO = anyTypeDAO;
+        this.groupDAO = groupDAO;
+        this.searchDAO = searchDAO;
+        this.groupDataBinder = groupDataBinder;
+        this.confParamOps = confParamOps;
+        this.exporter = exporter;
+        this.uwfAdapter = uwfAdapter;
+        this.gwfAdapter = gwfAdapter;
+        this.awfAdapter = awfAdapter;
+    }
 
     public boolean isSelfRegAllowed() {
         return confParamOps.get(AuthContextUtils.getDomain(), "selfRegistration.allowed", false, Boolean.class);
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
index 8b6c92e..afcb042 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
@@ -58,6 +58,7 @@ import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
 import org.apache.syncope.core.persistence.api.entity.task.TaskUtils;
 import org.apache.syncope.core.persistence.api.entity.task.TaskUtilsFactory;
 import org.apache.syncope.core.provisioning.api.data.TaskDataBinder;
+import org.apache.syncope.core.provisioning.api.job.JobManager;
 import org.apache.syncope.core.provisioning.api.job.JobNamer;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
 import org.apache.syncope.core.provisioning.api.notification.NotificationJobDelegate;
@@ -69,41 +70,56 @@ import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.quartz.JobDataMap;
 import org.quartz.JobKey;
 import org.quartz.SchedulerException;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.dao.InvalidDataAccessApiUsageException;
+import org.springframework.scheduling.quartz.SchedulerFactoryBean;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
 public class TaskLogic extends AbstractExecutableLogic<TaskTO> {
 
-    @Autowired
-    private TaskDAO taskDAO;
+    protected final TaskDAO taskDAO;
 
-    @Autowired
-    private TaskExecDAO taskExecDAO;
+    protected final TaskExecDAO taskExecDAO;
 
-    @Autowired
-    private ExternalResourceDAO resourceDAO;
+    protected final ExternalResourceDAO resourceDAO;
 
-    @Autowired
-    private NotificationDAO notificationDAO;
+    protected final NotificationDAO notificationDAO;
 
-    @Autowired
-    private ConfParamOps confParamOps;
+    protected final ConfParamOps confParamOps;
 
-    @Autowired
-    private TaskDataBinder binder;
+    protected final TaskDataBinder binder;
 
-    @Autowired
-    private PropagationTaskExecutor taskExecutor;
+    protected final PropagationTaskExecutor taskExecutor;
 
-    @Autowired
-    private NotificationJobDelegate notificationJobDelegate;
+    protected final NotificationJobDelegate notificationJobDelegate;
 
-    @Autowired
-    private TaskUtilsFactory taskUtilsFactory;
+    protected final TaskUtilsFactory taskUtilsFactory;
+
+    public TaskLogic(
+            final JobManager jobManager,
+            final SchedulerFactoryBean scheduler,
+            final TaskDAO taskDAO,
+            final TaskExecDAO taskExecDAO,
+            final ExternalResourceDAO resourceDAO,
+            final NotificationDAO notificationDAO,
+            final ConfParamOps confParamOps,
+            final TaskDataBinder binder,
+            final PropagationTaskExecutor taskExecutor,
+            final NotificationJobDelegate notificationJobDelegate,
+            final TaskUtilsFactory taskUtilsFactory) {
+
+        super(jobManager, scheduler);
+
+        this.taskDAO = taskDAO;
+        this.taskExecDAO = taskExecDAO;
+        this.resourceDAO = resourceDAO;
+        this.notificationDAO = notificationDAO;
+        this.confParamOps = confParamOps;
+        this.binder = binder;
+        this.taskExecutor = taskExecutor;
+        this.notificationJobDelegate = notificationJobDelegate;
+        this.taskUtilsFactory = taskUtilsFactory;
+    }
 
     @PreAuthorize("hasRole('" + IdRepoEntitlement.TASK_CREATE + "')")
     public <T extends SchedTaskTO> T createSchedTask(final TaskType type, final T taskTO) {
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
index 8ce3ab2..29e475d 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
@@ -46,9 +46,11 @@ import org.apache.syncope.common.lib.types.PatchOperation;
 import org.apache.syncope.common.lib.types.IdRepoEntitlement;
 import org.apache.syncope.core.persistence.api.dao.AccessTokenDAO;
 import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.DelegationDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
@@ -59,45 +61,61 @@ import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
 import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
+import org.apache.syncope.core.provisioning.java.utils.TemplateUtils;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
 /**
  * Note that this controller does not extend {@link AbstractTransactionalLogic}, hence does not provide any
  * Spring's Transactional logic at class level.
  */
-@Component
 public class UserLogic extends AbstractAnyLogic<UserTO, UserCR, UserUR> {
 
-    @Autowired
-    protected UserDAO userDAO;
+    protected final UserDAO userDAO;
 
-    @Autowired
-    protected GroupDAO groupDAO;
+    protected final GroupDAO groupDAO;
 
-    @Autowired
-    protected AnySearchDAO searchDAO;
+    protected final AnySearchDAO searchDAO;
 
-    @Autowired
-    protected AccessTokenDAO accessTokenDAO;
+    protected final AccessTokenDAO accessTokenDAO;
 
-    @Autowired
-    protected DelegationDAO delegationDAO;
+    protected final DelegationDAO delegationDAO;
 
-    @Autowired
-    protected ConfParamOps confParamOps;
+    protected final ConfParamOps confParamOps;
 
-    @Autowired
-    protected UserDataBinder binder;
+    protected final UserDataBinder binder;
 
-    @Autowired
-    protected UserProvisioningManager provisioningManager;
+    protected final UserProvisioningManager provisioningManager;
 
-    @Autowired
-    protected SyncopeLogic syncopeLogic;
+    protected final SyncopeLogic syncopeLogic;
+
+    public UserLogic(
+            final RealmDAO realmDAO,
+            final AnyTypeDAO anyTypeDAO,
+            final TemplateUtils templateUtils,
+            final UserDAO userDAO,
+            final GroupDAO groupDAO,
+            final AnySearchDAO searchDAO,
+            final AccessTokenDAO accessTokenDAO,
+            final DelegationDAO delegationDAO,
+            final ConfParamOps confParamOps,
+            final UserDataBinder binder,
+            final UserProvisioningManager provisioningManager,
+            final SyncopeLogic syncopeLogic) {
+
+        super(realmDAO, anyTypeDAO, templateUtils);
+
+        this.userDAO = userDAO;
+        this.groupDAO = groupDAO;
+        this.searchDAO = searchDAO;
+        this.accessTokenDAO = accessTokenDAO;
+        this.delegationDAO = delegationDAO;
+        this.confParamOps = confParamOps;
+        this.binder = binder;
+        this.provisioningManager = provisioningManager;
+        this.syncopeLogic = syncopeLogic;
+    }
 
     @PreAuthorize("isAuthenticated() and not(hasRole('" + IdRepoEntitlement.MUST_CHANGE_PASSWORD + "'))")
     @Transactional(readOnly = true)
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/AuditAccessor.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/AuditAccessor.java
index b8dcaf7..0e67a95 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/AuditAccessor.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/AuditAccessor.java
@@ -26,8 +26,6 @@ import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.config.LoggerConfig;
 import org.apache.syncope.common.lib.types.AuditLoggerName;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 import org.apache.syncope.core.persistence.api.entity.AuditConf;
 import org.apache.syncope.core.persistence.api.dao.AuditConfDAO;
@@ -37,15 +35,17 @@ import org.apache.syncope.core.persistence.api.dao.AuditConfDAO;
  *
  * @see AuditLoader
  */
-@Component
 public class AuditAccessor {
 
-    @Autowired
-    private AuditConfDAO auditDAO;
+    protected final AuditConfDAO auditConfDAO;
+
+    public AuditAccessor(final AuditConfDAO auditConfDAO) {
+        this.auditConfDAO = auditConfDAO;
+    }
 
     @Transactional
     public void synchronizeLoggingWithAudit(final LoggerContext ctx) {
-        Map<String, AuditConf> audits = auditDAO.findAll().stream().
+        Map<String, AuditConf> audits = auditConfDAO.findAll().stream().
                 collect(Collectors.toMap(
                         audit -> AuditLoggerName.getAuditEventLoggerName(AuthContextUtils.getDomain(), audit.getKey()),
                         Function.identity()));
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/AuditLoader.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/AuditLoader.java
index eaadf81..2456dc5 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/AuditLoader.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/AuditLoader.java
@@ -37,21 +37,25 @@ import org.apache.syncope.core.persistence.api.ImplementationLookup;
 import org.apache.syncope.core.persistence.api.SyncopeCoreLoader;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.support.AbstractBeanDefinition;
-import org.springframework.stereotype.Component;
 
-@Component
 public class AuditLoader implements SyncopeCoreLoader {
 
-    @Autowired
-    private AuditAccessor auditAccessor;
+    protected final AuditAccessor auditAccessor;
 
-    @Autowired
-    private ImplementationLookup implementationLookup;
+    protected final ImplementationLookup implementationLookup;
 
-    @Autowired
-    private LogicProperties props;
+    protected final LogicProperties props;
+
+    public AuditLoader(
+            final AuditAccessor auditAccessor,
+            final ImplementationLookup implementationLookup,
+            final LogicProperties props) {
+
+        this.auditAccessor = auditAccessor;
+        this.implementationLookup = implementationLookup;
+        this.props = props;
+    }
 
     @Override
     public int getOrder() {
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/EntitlementAccessor.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/EntitlementAccessor.java
index 8ae448a..6243c10 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/EntitlementAccessor.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/EntitlementAccessor.java
@@ -20,8 +20,6 @@ package org.apache.syncope.core.logic.init;
 
 import org.apache.syncope.common.lib.types.EntitlementsHolder;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
 /**
@@ -29,11 +27,13 @@ import org.springframework.transaction.annotation.Transactional;
  *
  * @see IdRepoEntitlementLoader
  */
-@Component
 public class EntitlementAccessor {
 
-    @Autowired
-    private AnyTypeDAO anyTypeDAO;
+    protected final AnyTypeDAO anyTypeDAO;
+
+    public EntitlementAccessor(final AnyTypeDAO anyTypeDAO) {
+        this.anyTypeDAO = anyTypeDAO;
+    }
 
     @Transactional(readOnly = true)
     public void addEntitlementsForAnyTypes() {
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/IdRepoEntitlementLoader.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/IdRepoEntitlementLoader.java
index ae1aa1a..c40687a 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/IdRepoEntitlementLoader.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/IdRepoEntitlementLoader.java
@@ -23,14 +23,14 @@ import org.apache.syncope.common.lib.types.EntitlementsHolder;
 import org.apache.syncope.common.lib.types.IdRepoEntitlement;
 import org.apache.syncope.core.persistence.api.SyncopeCoreLoader;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
 
-@Component
 public class IdRepoEntitlementLoader implements SyncopeCoreLoader {
 
-    @Autowired
-    private EntitlementAccessor entitlementAccessor;
+    protected final EntitlementAccessor entitlementAccessor;
+
+    public IdRepoEntitlementLoader(final EntitlementAccessor entitlementAccessor) {
+        this.entitlementAccessor = entitlementAccessor;
+    }
 
     @Override
     public int getOrder() {
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/IdRepoImplementationTypeLoader.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/IdRepoImplementationTypeLoader.java
index 0eded04..cf2fc3c 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/IdRepoImplementationTypeLoader.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/init/IdRepoImplementationTypeLoader.java
@@ -22,9 +22,7 @@ import org.apache.syncope.common.lib.types.IdRepoImplementationType;
 import org.apache.syncope.common.lib.types.ImplementationTypesHolder;
 import org.apache.syncope.core.persistence.api.SyncopeCoreLoader;
 import org.springframework.core.Ordered;
-import org.springframework.stereotype.Component;
 
-@Component
 public class IdRepoImplementationTypeLoader implements SyncopeCoreLoader {
 
     @Override
diff --git a/core/idrepo/logic/src/main/resources/META-INF/spring.factories b/core/idrepo/logic/src/main/resources/META-INF/spring.factories
index eb5b93f..0367f7d 100644
--- a/core/idrepo/logic/src/main/resources/META-INF/spring.factories
+++ b/core/idrepo/logic/src/main/resources/META-INF/spring.factories
@@ -16,4 +16,4 @@
 # under the License.
 
 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-  org.apache.syncope.core.logic.LogicContext
+  org.apache.syncope.core.logic.IdRepoLogicContext
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/CheckDomainFilter.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/CheckDomainFilter.java
index 5b3062d..17a1336 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/CheckDomainFilter.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/CheckDomainFilter.java
@@ -31,7 +31,6 @@ import org.apache.syncope.common.lib.to.ErrorTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.core.persistence.api.DomainHolder;
-import org.springframework.beans.factory.annotation.Autowired;
 
 /**
  * Checks that requested Domain exists.
@@ -40,8 +39,11 @@ import org.springframework.beans.factory.annotation.Autowired;
 @PreMatching
 public class CheckDomainFilter implements ContainerRequestFilter {
 
-    @Autowired
-    private DomainHolder domainHolder;
+    protected final DomainHolder domainHolder;
+
+    public CheckDomainFilter(final DomainHolder domainHolder) {
+        this.domainHolder = domainHolder;
+    }
 
     @Override
     public void filter(final ContainerRequestContext reqContext) throws IOException {
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/IdRepoRESTCXFContext.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/IdRepoRESTCXFContext.java
new file mode 100644
index 0000000..cecbac3
--- /dev/null
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/IdRepoRESTCXFContext.java
@@ -0,0 +1,509 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.rest.cxf;
+
+import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
+import com.fasterxml.jackson.jaxrs.xml.JacksonXMLProvider;
+import com.fasterxml.jackson.jaxrs.yaml.JacksonYAMLProvider;
+import io.swagger.v3.oas.models.security.SecurityScheme;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.servlet.ServletRequestListener;
+import org.apache.cxf.Bus;
+import org.apache.cxf.endpoint.Server;
+import org.apache.cxf.jaxrs.ext.search.SearchContextImpl;
+import org.apache.cxf.jaxrs.ext.search.SearchContextProvider;
+import org.apache.cxf.jaxrs.ext.search.SearchUtils;
+import org.apache.cxf.jaxrs.openapi.OpenApiFeature;
+import org.apache.cxf.jaxrs.spring.JAXRSServerFactoryBeanDefinitionParser.SpringJAXRSServerFactoryBean;
+import org.apache.cxf.jaxrs.validation.JAXRSBeanValidationInInterceptor;
+import org.apache.cxf.transport.common.gzip.GZIPInInterceptor;
+import org.apache.cxf.transport.common.gzip.GZIPOutInterceptor;
+import org.apache.cxf.validation.BeanValidationProvider;
+import org.apache.syncope.common.lib.jackson.SyncopeObjectMapper;
+import org.apache.syncope.common.lib.jackson.SyncopeXmlMapper;
+import org.apache.syncope.common.lib.jackson.SyncopeYAMLMapper;
+import org.apache.syncope.common.lib.search.SyncopeFiqlParser;
+import org.apache.syncope.common.rest.api.DateParamConverterProvider;
+import org.apache.syncope.common.rest.api.service.AccessTokenService;
+import org.apache.syncope.common.rest.api.service.AnyObjectService;
+import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
+import org.apache.syncope.common.rest.api.service.AnyTypeService;
+import org.apache.syncope.common.rest.api.service.ApplicationService;
+import org.apache.syncope.common.rest.api.service.AuditService;
+import org.apache.syncope.common.rest.api.service.DelegationService;
+import org.apache.syncope.common.rest.api.service.DynRealmService;
+import org.apache.syncope.common.rest.api.service.GroupService;
+import org.apache.syncope.common.rest.api.service.ImplementationService;
+import org.apache.syncope.common.rest.api.service.MailTemplateService;
+import org.apache.syncope.common.rest.api.service.NotificationService;
+import org.apache.syncope.common.rest.api.service.PolicyService;
+import org.apache.syncope.common.rest.api.service.RealmService;
+import org.apache.syncope.common.rest.api.service.RelationshipTypeService;
+import org.apache.syncope.common.rest.api.service.ReportService;
+import org.apache.syncope.common.rest.api.service.ReportTemplateService;
+import org.apache.syncope.common.rest.api.service.RoleService;
+import org.apache.syncope.common.rest.api.service.SchemaService;
+import org.apache.syncope.common.rest.api.service.SecurityQuestionService;
+import org.apache.syncope.common.rest.api.service.SyncopeService;
+import org.apache.syncope.common.rest.api.service.TaskService;
+import org.apache.syncope.common.rest.api.service.UserSelfService;
+import org.apache.syncope.common.rest.api.service.UserService;
+import org.apache.syncope.core.logic.AccessTokenLogic;
+import org.apache.syncope.core.logic.AnyObjectLogic;
+import org.apache.syncope.core.logic.AnyTypeClassLogic;
+import org.apache.syncope.core.logic.AnyTypeLogic;
+import org.apache.syncope.core.logic.ApplicationLogic;
+import org.apache.syncope.core.logic.AuditLogic;
+import org.apache.syncope.core.logic.DelegationLogic;
+import org.apache.syncope.core.logic.DynRealmLogic;
+import org.apache.syncope.core.logic.GroupLogic;
+import org.apache.syncope.core.logic.ImplementationLogic;
+import org.apache.syncope.core.logic.MailTemplateLogic;
+import org.apache.syncope.core.logic.NotificationLogic;
+import org.apache.syncope.core.logic.PolicyLogic;
+import org.apache.syncope.core.logic.RealmLogic;
+import org.apache.syncope.core.logic.RelationshipTypeLogic;
+import org.apache.syncope.core.logic.ReportLogic;
+import org.apache.syncope.core.logic.ReportTemplateLogic;
+import org.apache.syncope.core.logic.RoleLogic;
+import org.apache.syncope.core.logic.SchemaLogic;
+import org.apache.syncope.core.logic.SecurityQuestionLogic;
+import org.apache.syncope.core.logic.SyncopeLogic;
+import org.apache.syncope.core.logic.TaskLogic;
+import org.apache.syncope.core.logic.UserLogic;
+import org.apache.syncope.core.persistence.api.DomainHolder;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.BatchDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.search.SearchCondVisitor;
+import org.apache.syncope.core.rest.cxf.service.AccessTokenServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.AnyObjectServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.AnyTypeClassServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.AnyTypeServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.ApplicationServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.AuditServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.DelegationServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.DynRealmServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.GroupServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.ImplementationServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.MailTemplateServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.NotificationServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.PolicyServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.RealmServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.RelationshipTypeServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.ReportServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.ReportTemplateServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.RoleServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.SchemaServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.SecurityQuestionServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.SyncopeServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.TaskServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.UserSelfServiceImpl;
+import org.apache.syncope.core.rest.cxf.service.UserServiceImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+@PropertySource("classpath:errorMessages.properties")
+@Configuration
+public class IdRepoRESTCXFContext {
+
+    @Autowired
+    private SearchCondVisitor searchCondVisitor;
+
+    @Autowired
+    private Bus bus;
+
+    @Autowired
+    private ApplicationContext ctx;
+
+    @ConditionalOnMissingBean
+    @Bean
+    public ThreadPoolTaskExecutor batchExecutor() {
+        ThreadPoolTaskExecutor batchExecutor = new ThreadPoolTaskExecutor();
+        batchExecutor.setCorePoolSize(10);
+        batchExecutor.setThreadNamePrefix("Batch-");
+        batchExecutor.initialize();
+        return batchExecutor;
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public DateParamConverterProvider dateParamConverterProvider() {
+        return new DateParamConverterProvider();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public JacksonJsonProvider jsonProvider() {
+        JacksonJsonProvider jsonProvider = new JacksonJsonProvider();
+        jsonProvider.setMapper(new SyncopeObjectMapper());
+        return jsonProvider;
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public JacksonXMLProvider xmlProvider() {
+        JacksonXMLProvider xmlProvider = new JacksonXMLProvider();
+        xmlProvider.setMapper(new SyncopeXmlMapper());
+        return xmlProvider;
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public JacksonYAMLProvider yamlProvider() {
+        JacksonYAMLProvider yamlProvider = new JacksonYAMLProvider();
+        yamlProvider.setMapper(new SyncopeYAMLMapper());
+        return yamlProvider;
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public BeanValidationProvider validationProvider() {
+        return new BeanValidationProvider();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public JAXRSBeanValidationInInterceptor validationInInterceptor() {
+        JAXRSBeanValidationInInterceptor validationInInterceptor = new JAXRSBeanValidationInInterceptor();
+        validationInInterceptor.setProvider(validationProvider());
+        return validationInInterceptor;
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public GZIPInInterceptor gzipInInterceptor() {
+        return new GZIPInInterceptor();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public GZIPOutInterceptor gzipOutInterceptor() {
+        GZIPOutInterceptor gzipOutInterceptor = new GZIPOutInterceptor();
+        gzipOutInterceptor.setThreshold(0);
+        gzipOutInterceptor.setForce(true);
+        return gzipOutInterceptor;
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public RestServiceExceptionMapper restServiceExceptionMapper(final Environment env) {
+        return new RestServiceExceptionMapper(env);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public SearchContextProvider searchContextProvider() {
+        return new SearchContextProvider();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public CheckDomainFilter checkDomainFilter(final DomainHolder domainHolder) {
+        return new CheckDomainFilter(domainHolder);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public AddDomainFilter addDomainFilter() {
+        return new AddDomainFilter();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public AddETagFilter addETagFilter() {
+        return new AddETagFilter();
+    }
+
+    private String version() {
+        return ctx.getEnvironment().getProperty("version");
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public OpenApiFeature openapiFeature() {
+        OpenApiFeature openapiFeature = new OpenApiFeature();
+        openapiFeature.setTitle("Apache Syncope");
+        openapiFeature.setVersion(version());
+        openapiFeature.setDescription("Apache Syncope " + version());
+        openapiFeature.setContactName("The Apache Syncope community");
+        openapiFeature.setContactEmail("dev@syncope.apache.org");
+        openapiFeature.setContactUrl("http://syncope.apache.org");
+        openapiFeature.setScan(false);
+        openapiFeature.setResourcePackages(Set.of("org.apache.syncope.common.rest.api.service"));
+
+        SyncopeOpenApiCustomizer openApiCustomizer = new SyncopeOpenApiCustomizer(ctx.getEnvironment());
+        openApiCustomizer.setDynamicBasePath(false);
+        openApiCustomizer.setReplaceTags(false);
+        openapiFeature.setCustomizer(openApiCustomizer);
+
+        Map<String, SecurityScheme> securityDefinitions = new HashMap<>();
+        SecurityScheme basicAuth = new SecurityScheme();
+        basicAuth.setType(SecurityScheme.Type.HTTP);
+        basicAuth.setScheme("basic");
+        securityDefinitions.put("BasicAuthentication", basicAuth);
+        SecurityScheme bearer = new SecurityScheme();
+        bearer.setType(SecurityScheme.Type.HTTP);
+        bearer.setScheme("bearer");
+        bearer.setBearerFormat("JWT");
+        securityDefinitions.put("Bearer", bearer);
+        openapiFeature.setSecurityDefinitions(securityDefinitions);
+
+        return openapiFeature;
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public Server restContainer(
+            final CheckDomainFilter checkDomainFilter,
+            final RestServiceExceptionMapper restServiceExceptionMapper) {
+
+        SpringJAXRSServerFactoryBean restContainer = new SpringJAXRSServerFactoryBean();
+        restContainer.setBus(bus);
+        restContainer.setAddress("/");
+        restContainer.setStaticSubresourceResolution(true);
+        restContainer.setBasePackages(List.of(
+                "org.apache.syncope.common.rest.api.service",
+                "org.apache.syncope.core.rest.cxf.service"));
+
+        Map<String, Object> properties = new HashMap<>();
+        properties.put(SearchContextImpl.CUSTOM_SEARCH_PARSER_CLASS_PROPERTY, SyncopeFiqlParser.class.getName());
+        properties.put(SearchUtils.LAX_PROPERTY_MATCH, "true");
+        properties.put("convert.wadl.resources.to.dom", "false");
+        restContainer.setProperties(properties);
+
+        restContainer.setProviders(List.of(
+                dateParamConverterProvider(),
+                jsonProvider(),
+                xmlProvider(),
+                yamlProvider(),
+                restServiceExceptionMapper,
+                searchContextProvider(),
+                checkDomainFilter,
+                addDomainFilter(),
+                addETagFilter()));
+
+        restContainer.setInInterceptors(List.of(
+                gzipInInterceptor(),
+                validationInInterceptor()));
+
+        restContainer.setOutInterceptors(List.of(gzipOutInterceptor()));
+
+        restContainer.setFeatures(List.of(openapiFeature()));
+
+        restContainer.setApplicationContext(ctx);
+        return restContainer.create();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public ServletListenerRegistrationBean<ServletRequestListener> listenerRegistrationBean() {
+        ServletListenerRegistrationBean<ServletRequestListener> bean = new ServletListenerRegistrationBean<>();
+        bean.setListener(new ThreadLocalCleanupListener());
+        return bean;
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public AccessTokenService accessTokenService(final AccessTokenLogic accessTokenLogic) {
+        return new AccessTokenServiceImpl(accessTokenLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public AnyObjectService anyObjectService(final AnyObjectDAO anyObjectDAO, final AnyObjectLogic anyObjectLogic) {
+        return new AnyObjectServiceImpl(searchCondVisitor, anyObjectDAO, anyObjectLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public AnyTypeClassService anyTypeClassService(final AnyTypeClassLogic anyTypeClassLogic) {
+        return new AnyTypeClassServiceImpl(anyTypeClassLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public AnyTypeService anyTypeService(final AnyTypeLogic anyTypeLogic) {
+        return new AnyTypeServiceImpl(anyTypeLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public ApplicationService applicationService(final ApplicationLogic applicationLogic) {
+        return new ApplicationServiceImpl(applicationLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public AuditService auditService(final AuditLogic auditLogic) {
+        return new AuditServiceImpl(auditLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public DelegationService delegationService(final DelegationLogic delegationLogic) {
+        return new DelegationServiceImpl(delegationLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public DynRealmService dynRealmService(final DynRealmLogic dynRealmLogic) {
+        return new DynRealmServiceImpl(dynRealmLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public GroupService groupService(final GroupDAO groupDAO, final GroupLogic groupLogic) {
+        return new GroupServiceImpl(searchCondVisitor, groupDAO, groupLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public ImplementationService implementationService(final ImplementationLogic implementationLogic) {
+        return new ImplementationServiceImpl(implementationLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public MailTemplateService mailTemplateService(final MailTemplateLogic mailTemplateLogic) {
+        return new MailTemplateServiceImpl(mailTemplateLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public NotificationService notificationService(final NotificationLogic notificationLogic) {
+        return new NotificationServiceImpl(notificationLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public PolicyService policyService(final PolicyLogic policyLogic) {
+        return new PolicyServiceImpl(policyLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public RealmService realmService(final RealmLogic realmLogic) {
+        return new RealmServiceImpl(realmLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public RelationshipTypeService relationshipTypeService(final RelationshipTypeLogic relationshipTypeLogic) {
+        return new RelationshipTypeServiceImpl(relationshipTypeLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public ReportService reportService(final ReportLogic reportLogic) {
+        return new ReportServiceImpl(reportLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public ReportTemplateService reportTemplateService(final ReportTemplateLogic reportTemplateLogic) {
+        return new ReportTemplateServiceImpl(reportTemplateLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public RoleService roleService(final RoleLogic roleLogic) {
+        return new RoleServiceImpl(roleLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public SchemaService schemaService(final SchemaLogic schemaLogic) {
+        return new SchemaServiceImpl(schemaLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public SecurityQuestionService securityQuestionService(final SecurityQuestionLogic securityQuestionLogic) {
+        return new SecurityQuestionServiceImpl(securityQuestionLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public SyncopeService syncopeService(
+            final SyncopeLogic syncopeLogic,
+            final ThreadPoolTaskExecutor batchExecutor,
+            final BatchDAO batchDAO,
+            final EntityFactory entityFactory) {
+
+        return new SyncopeServiceImpl(syncopeLogic, batchExecutor, bus, batchDAO, entityFactory);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public TaskService taskService(final TaskLogic taskLogic) {
+        return new TaskServiceImpl(taskLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public UserSelfService userSelfService(final UserLogic userLogic, final SyncopeLogic syncopeLogic) {
+        return new UserSelfServiceImpl(userLogic, syncopeLogic);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public UserService userService(final UserDAO userDAO, final UserLogic userLogic) {
+        return new UserServiceImpl(searchCondVisitor, userDAO, userLogic);
+    }
+}
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RESTCXFContext.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RESTCXFContext.java
deleted file mode 100644
index d836bcf..0000000
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RESTCXFContext.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.rest.cxf;
-
-import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
-import com.fasterxml.jackson.jaxrs.xml.JacksonXMLProvider;
-import com.fasterxml.jackson.jaxrs.yaml.JacksonYAMLProvider;
-import io.swagger.v3.oas.models.security.SecurityScheme;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Executor;
-import javax.servlet.ServletRequestListener;
-import org.apache.cxf.Bus;
-import org.apache.cxf.endpoint.Server;
-import org.apache.cxf.jaxrs.ext.search.SearchContextImpl;
-import org.apache.cxf.jaxrs.ext.search.SearchContextProvider;
-import org.apache.cxf.jaxrs.ext.search.SearchUtils;
-import org.apache.cxf.jaxrs.openapi.OpenApiFeature;
-import org.apache.cxf.jaxrs.spring.JAXRSServerFactoryBeanDefinitionParser.SpringJAXRSServerFactoryBean;
-import org.apache.cxf.jaxrs.validation.JAXRSBeanValidationInInterceptor;
-import org.apache.cxf.transport.common.gzip.GZIPInInterceptor;
-import org.apache.cxf.transport.common.gzip.GZIPOutInterceptor;
-import org.apache.cxf.validation.BeanValidationProvider;
-import org.apache.syncope.common.lib.jackson.SyncopeObjectMapper;
-import org.apache.syncope.common.lib.jackson.SyncopeXmlMapper;
-import org.apache.syncope.common.lib.jackson.SyncopeYAMLMapper;
-import org.apache.syncope.common.lib.search.SyncopeFiqlParser;
-import org.apache.syncope.common.rest.api.DateParamConverterProvider;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.PropertySource;
-import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
-
-@ComponentScan("org.apache.syncope.core.rest.cxf.service")
-@PropertySource("classpath:errorMessages.properties")
-@Configuration
-public class RESTCXFContext {
-
-    @Autowired
-    private Bus bus;
-
-    @Autowired
-    private ApplicationContext ctx;
-
-    @Bean
-    public Executor batchExecutor() {
-        ThreadPoolTaskExecutor batchExecutor = new ThreadPoolTaskExecutor();
-        batchExecutor.setCorePoolSize(10);
-        batchExecutor.setThreadNamePrefix("Batch-");
-        batchExecutor.initialize();
-        return batchExecutor;
-    }
-
-    @Bean
-    public DateParamConverterProvider dateParamConverterProvider() {
-        return new DateParamConverterProvider();
-    }
-
-    @Bean
-    public JacksonJsonProvider jsonProvider() {
-        JacksonJsonProvider jsonProvider = new JacksonJsonProvider();
-        jsonProvider.setMapper(new SyncopeObjectMapper());
-        return jsonProvider;
-    }
-
-    @Bean
-    public JacksonXMLProvider xmlProvider() {
-        JacksonXMLProvider xmlProvider = new JacksonXMLProvider();
-        xmlProvider.setMapper(new SyncopeXmlMapper());
-        return xmlProvider;
-    }
-
-    @Bean
-    public JacksonYAMLProvider yamlProvider() {
-        JacksonYAMLProvider yamlProvider = new JacksonYAMLProvider();
-        yamlProvider.setMapper(new SyncopeYAMLMapper());
-        return yamlProvider;
-    }
-
-    @Bean
-    public BeanValidationProvider validationProvider() {
-        return new BeanValidationProvider();
-    }
-
-    @Bean
-    public JAXRSBeanValidationInInterceptor validationInInterceptor() {
-        JAXRSBeanValidationInInterceptor validationInInterceptor = new JAXRSBeanValidationInInterceptor();
-        validationInInterceptor.setProvider(validationProvider());
-        return validationInInterceptor;
-    }
-
-    @Bean
-    public GZIPInInterceptor gzipInInterceptor() {
-        return new GZIPInInterceptor();
-    }
-
-    @Bean
-    public GZIPOutInterceptor gzipOutInterceptor() {
-        GZIPOutInterceptor gzipOutInterceptor = new GZIPOutInterceptor();
-        gzipOutInterceptor.setThreshold(0);
-        gzipOutInterceptor.setForce(true);
-        return gzipOutInterceptor;
-    }
-
-    @Bean
-    public RestServiceExceptionMapper restServiceExceptionMapper() {
-        return new RestServiceExceptionMapper();
-    }
-
-    @Bean
-    public SearchContextProvider searchContextProvider() {
-        return new SearchContextProvider();
-    }
-
-    @Bean
-    public CheckDomainFilter checkDomainFilter() {
-        return new CheckDomainFilter();
-    }
-
-    @Bean
-    public AddDomainFilter addDomainFilter() {
-        return new AddDomainFilter();
-    }
-
-    @Bean
-    public AddETagFilter addETagFilter() {
-        return new AddETagFilter();
-    }
-
-    private String version() {
-        return ctx.getEnvironment().getProperty("version");
-    }
-
-    @Bean
-    public OpenApiFeature openapiFeature() {
-        OpenApiFeature openapiFeature = new OpenApiFeature();
-        openapiFeature.setTitle("Apache Syncope");
-        openapiFeature.setVersion(version());
-        openapiFeature.setDescription("Apache Syncope " + version());
-        openapiFeature.setContactName("The Apache Syncope community");
-        openapiFeature.setContactEmail("dev@syncope.apache.org");
-        openapiFeature.setContactUrl("http://syncope.apache.org");
-        openapiFeature.setScan(false);
-        openapiFeature.setResourcePackages(Set.of("org.apache.syncope.common.rest.api.service"));
-
-        SyncopeOpenApiCustomizer openApiCustomizer = new SyncopeOpenApiCustomizer(ctx.getEnvironment());
-        openApiCustomizer.setDynamicBasePath(false);
-        openApiCustomizer.setReplaceTags(false);
-        openapiFeature.setCustomizer(openApiCustomizer);
-
-        Map<String, SecurityScheme> securityDefinitions = new HashMap<>();
-        SecurityScheme basicAuth = new SecurityScheme();
-        basicAuth.setType(SecurityScheme.Type.HTTP);
-        basicAuth.setScheme("basic");
-        securityDefinitions.put("BasicAuthentication", basicAuth);
-        SecurityScheme bearer = new SecurityScheme();
-        bearer.setType(SecurityScheme.Type.HTTP);
-        bearer.setScheme("bearer");
-        bearer.setBearerFormat("JWT");
-        securityDefinitions.put("Bearer", bearer);
-        openapiFeature.setSecurityDefinitions(securityDefinitions);
-
-        return openapiFeature;
-    }
-
-    @Bean
-    public Server restContainer() {
-        SpringJAXRSServerFactoryBean restContainer = new SpringJAXRSServerFactoryBean();
-        restContainer.setBus(bus);
-        restContainer.setAddress("/");
-        restContainer.setStaticSubresourceResolution(true);
-        restContainer.setBasePackages(List.of(
-                "org.apache.syncope.common.rest.api.service",
-                "org.apache.syncope.core.rest.cxf.service"));
-
-        Map<String, Object> properties = new HashMap<>();
-        properties.put(SearchContextImpl.CUSTOM_SEARCH_PARSER_CLASS_PROPERTY, SyncopeFiqlParser.class.getName());
-        properties.put(SearchUtils.LAX_PROPERTY_MATCH, "true");
-        properties.put("convert.wadl.resources.to.dom", "false");
-        restContainer.setProperties(properties);
-
-        restContainer.setProviders(List.of(
-                dateParamConverterProvider(),
-                jsonProvider(),
-                xmlProvider(),
-                yamlProvider(),
-                restServiceExceptionMapper(),
-                searchContextProvider(),
-                checkDomainFilter(),
-                addDomainFilter(),
-                addETagFilter()));
-
-        restContainer.setInInterceptors(List.of(
-                gzipInInterceptor(),
-                validationInInterceptor()));
-
-        restContainer.setOutInterceptors(List.of(gzipOutInterceptor()));
-
-        restContainer.setFeatures(List.of(openapiFeature()));
-
-        restContainer.setApplicationContext(ctx);
-        return restContainer.create();
-    }
-
-    @Bean
-    public ServletListenerRegistrationBean<ServletRequestListener> listenerRegistrationBean() {
-        ServletListenerRegistrationBean<ServletRequestListener> bean = new ServletListenerRegistrationBean<>();
-        bean.setListener(new ThreadLocalCleanupListener());
-        return bean;
-    }
-}
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
index e0a2479..71243cc 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
@@ -55,7 +55,6 @@ import org.identityconnectors.framework.common.exceptions.ConfigurationException
 import org.identityconnectors.framework.common.exceptions.ConnectorException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.env.Environment;
 import org.springframework.dao.DataIntegrityViolationException;
 import org.springframework.dao.UncategorizedDataAccessException;
@@ -69,9 +68,6 @@ public class RestServiceExceptionMapper implements ExceptionMapper<Exception> {
 
     private final ValidationExceptionMapper validationEM = new ValidationExceptionMapper();
 
-    @Autowired
-    private Environment env;
-
     private static final String UNIQUE_MSG_KEY = "UniqueConstraintViolation";
 
     private static final Map<String, String> EXCEPTION_CODE_MAP = new HashMap<>() {
@@ -84,6 +80,12 @@ public class RestServiceExceptionMapper implements ExceptionMapper<Exception> {
         }
     };
 
+    protected final Environment env;
+
+    public RestServiceExceptionMapper(final Environment env) {
+        this.env = env;
+    }
+
     @Override
     public Response toResponse(final Exception ex) {
         LOG.error("Exception thrown", ex);
@@ -170,7 +172,7 @@ public class RestServiceExceptionMapper implements ExceptionMapper<Exception> {
     }
 
     private static ResponseBuilder getSyncopeClientCompositeExceptionResponse(
-        final SyncopeClientCompositeException ex) {
+            final SyncopeClientCompositeException ex) {
         if (ex.getExceptions().size() == 1) {
             return getSyncopeClientExceptionResponse(ex.getExceptions().iterator().next());
         }
@@ -317,6 +319,6 @@ public class RestServiceExceptionMapper implements ExceptionMapper<Exception> {
         }
 
         return Optional.ofNullable(message)
-            .orElseGet(() -> (ex.getCause() == null) ? ex.getMessage() : ex.getCause().getMessage());
+                .orElseGet(() -> (ex.getCause() == null) ? ex.getMessage() : ex.getCause().getMessage());
     }
 }
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
index 1485786..2eb2cda 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
@@ -52,12 +52,16 @@ import org.apache.syncope.core.logic.AbstractAnyLogic;
 import org.apache.syncope.core.persistence.api.dao.AnyDAO;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+import org.apache.syncope.core.persistence.api.search.SearchCondVisitor;
 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.apache.syncope.core.spring.security.SecureRandomUtils;
 
 public abstract class AbstractAnyService<TO extends AnyTO, CR extends AnyCR, UR extends AnyUR>
-        extends AbstractServiceImpl
-        implements AnyService<TO> {
+        extends AbstractSearchService implements AnyService<TO> {
+
+    public AbstractAnyService(final SearchCondVisitor searchCondVisitor) {
+        super(searchCondVisitor);
+    }
 
     protected abstract AnyDAO<?> getAnyDAO();
 
@@ -158,7 +162,7 @@ public abstract class AbstractAnyService<TO extends AnyTO, CR extends AnyCR, UR
         return modificationResponse(updated);
     }
 
-    private void addUpdateOrReplaceAttr(
+    protected void addUpdateOrReplaceAttr(
             final String key, final SchemaType schemaType, final Attr attrTO, final PatchOperation operation) {
 
         if (attrTO.getSchema() == null) {
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractExecutableService.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractExecutableService.java
index 48d238c..db8128b 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractExecutableService.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractExecutableService.java
@@ -36,7 +36,7 @@ import org.apache.syncope.common.rest.api.service.ExecutableService;
 import org.apache.syncope.core.logic.AbstractExecutableLogic;
 import org.apache.syncope.core.spring.security.SecureRandomUtils;
 
-public abstract class AbstractExecutableService extends AbstractServiceImpl implements ExecutableService {
+public abstract class AbstractExecutableService extends AbstractService implements ExecutableService {
 
     protected abstract AbstractExecutableLogic<?> getExecutableLogic();
 
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractSearchService.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractSearchService.java
new file mode 100644
index 0000000..28537e0
--- /dev/null
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractSearchService.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.rest.cxf.service;
+
+import static org.apache.syncope.core.rest.cxf.service.AbstractService.LOG;
+
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.cxf.jaxrs.ext.search.SearchBean;
+import org.apache.cxf.jaxrs.ext.search.SearchCondition;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+import org.apache.syncope.core.persistence.api.search.SearchCondVisitor;
+
+public abstract class AbstractSearchService extends AbstractService {
+
+    protected final SearchCondVisitor searchCondVisitor;
+
+    public AbstractSearchService(final SearchCondVisitor searchCondVisitor) {
+        this.searchCondVisitor = searchCondVisitor;
+    }
+
+    protected SearchCond getSearchCond(final String fiql, final String realm) {
+        try {
+            searchCondVisitor.setRealm(realm);
+            SearchCondition<SearchBean> sc = searchContext.getCondition(fiql, SearchBean.class);
+            sc.accept(searchCondVisitor);
+
+            return searchCondVisitor.getQuery();
+        } catch (Exception e) {
+            LOG.error("Invalid FIQL expression: {}", fiql, e);
+
+            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidSearchExpression);
+            sce.getElements().add(fiql);
+            sce.getElements().add(ExceptionUtils.getRootCauseMessage(e));
+            throw sce;
+        }
+    }
+}
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractService.java
similarity index 87%
rename from core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java
rename to core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractService.java
index ae3c903..ac8a766 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractService.java
@@ -28,10 +28,7 @@ import javax.ws.rs.core.UriBuilder;
 import javax.ws.rs.core.UriInfo;
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.apache.cxf.jaxrs.ext.MessageContext;
-import org.apache.cxf.jaxrs.ext.search.SearchBean;
-import org.apache.cxf.jaxrs.ext.search.SearchCondition;
 import org.apache.cxf.jaxrs.ext.search.SearchContext;
 import org.apache.syncope.common.lib.BaseBean;
 import org.apache.syncope.common.lib.SyncopeClientException;
@@ -43,16 +40,13 @@ import org.apache.syncope.common.rest.api.service.JAXRSService;
 import org.apache.syncope.common.rest.api.Preference;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.core.persistence.api.dao.AnyDAO;
-import org.apache.syncope.core.persistence.api.search.SearchCondVisitor;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
-import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
 
-public abstract class AbstractServiceImpl implements JAXRSService {
+public abstract class AbstractService implements JAXRSService {
 
-    protected static final Logger LOG = LoggerFactory.getLogger(AbstractServiceImpl.class);
+    protected static final Logger LOG = LoggerFactory.getLogger(AbstractService.class);
 
     protected static final String OPTIONS_ALLOW = "GET,POST,OPTIONS,HEAD";
 
@@ -65,9 +59,6 @@ public abstract class AbstractServiceImpl implements JAXRSService {
     @Context
     protected SearchContext searchContext;
 
-    @Autowired
-    protected SearchCondVisitor searchCondVisitor;
-
     protected String getActualKey(final AnyDAO<?> dao, final String pretendingKey) {
         String actualKey = pretendingKey;
         if (!SyncopeConstants.UUID_PATTERN.matcher(pretendingKey).matches()) {
@@ -163,23 +154,6 @@ public abstract class AbstractServiceImpl implements JAXRSService {
         }
     }
 
-    protected SearchCond getSearchCond(final String fiql, final String realm) {
-        try {
-            searchCondVisitor.setRealm(realm);
-            SearchCondition<SearchBean> sc = searchContext.getCondition(fiql, SearchBean.class);
-            sc.accept(searchCondVisitor);
-
-            return searchCondVisitor.getQuery();
-        } catch (Exception e) {
-            LOG.error("Invalid FIQL expression: {}", fiql, e);
-
-            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidSearchExpression);
-            sce.getElements().add(fiql);
-            sce.getElements().add(ExceptionUtils.getRootCauseMessage(e));
-            throw sce;
-        }
-    }
-
     protected List<OrderByClause> getOrderByClauses(final String orderBy) {
         if (StringUtils.isBlank(orderBy)) {
             return List.of();
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AccessTokenServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AccessTokenServiceImpl.java
index 2b09324..c1b80b8 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AccessTokenServiceImpl.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AccessTokenServiceImpl.java
@@ -30,13 +30,15 @@ import org.apache.syncope.common.rest.api.beans.AccessTokenQuery;
 import org.springframework.stereotype.Service;
 import org.apache.syncope.common.rest.api.service.AccessTokenService;
 import org.apache.syncope.core.logic.AccessTokenLogic;
-import org.springframework.beans.factory.annotation.Autowired;
 
 @Service
-public class AccessTokenServiceImpl extends AbstractServiceImpl implements AccessTokenService {
+public class AccessTokenServiceImpl extends AbstractService implements AccessTokenService {
 
-    @Autowired
-    private AccessTokenLogic logic;
+    protected final AccessTokenLogic logic;
+
+    public AccessTokenServiceImpl(final AccessTokenLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public Response login() {
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceImpl.java
index 2b1f4cf..b63643a 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceImpl.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceImpl.java
@@ -34,18 +34,26 @@ import org.apache.syncope.core.logic.AbstractAnyLogic;
 import org.apache.syncope.core.logic.AnyObjectLogic;
 import org.apache.syncope.core.persistence.api.dao.AnyDAO;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.syncope.core.persistence.api.search.SearchCondVisitor;
 import org.springframework.stereotype.Service;
 
 @Service
 public class AnyObjectServiceImpl extends AbstractAnyService<AnyObjectTO, AnyObjectCR, AnyObjectUR>
         implements AnyObjectService {
 
-    @Autowired
-    private AnyObjectDAO anyObjectDAO;
+    protected final AnyObjectDAO anyObjectDAO;
 
-    @Autowired
-    private AnyObjectLogic logic;
+    protected final AnyObjectLogic logic;
+
+    public AnyObjectServiceImpl(
+            final SearchCondVisitor searchCondVisitor,
+            final AnyObjectDAO anyObjectDAO,
+            final AnyObjectLogic logic) {
+
+        super(searchCondVisitor);
+        this.anyObjectDAO = anyObjectDAO;
+        this.logic = logic;
+    }
 
     @Override
     protected AnyDAO<?> getAnyDAO() {
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeClassServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeClassServiceImpl.java
index bd3149f..34dee57 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeClassServiceImpl.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeClassServiceImpl.java
@@ -25,14 +25,16 @@ import org.apache.syncope.common.lib.to.AnyTypeClassTO;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
 import org.apache.syncope.core.logic.AnyTypeClassLogic;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
-public class AnyTypeClassServiceImpl extends AbstractServiceImpl implements AnyTypeClassService {
+public class AnyTypeClassServiceImpl extends AbstractService implements AnyTypeClassService {
 
-    @Autowired
-    private AnyTypeClassLogic logic;
+    protected final AnyTypeClassLogic logic;
+
+    public AnyTypeClassServiceImpl(final AnyTypeClassLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public List<AnyTypeClassTO> list() {
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeServiceImpl.java
index 9dd4982..1423e61 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeServiceImpl.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeServiceImpl.java
@@ -25,14 +25,16 @@ import org.apache.syncope.common.lib.to.AnyTypeTO;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.AnyTypeService;
 import org.apache.syncope.core.logic.AnyTypeLogic;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
-public class AnyTypeServiceImpl extends AbstractServiceImpl implements AnyTypeService {
+public class AnyTypeServiceImpl extends AbstractService implements AnyTypeService {
 
-    @Autowired
-    private AnyTypeLogic logic;
+    protected final AnyTypeLogic logic;
+
+    public AnyTypeServiceImpl(final AnyTypeLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public List<AnyTypeTO> list() {
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ApplicationServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ApplicationServiceImpl.java
index a0354ee..e9e7bf5 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ApplicationServiceImpl.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ApplicationServiceImpl.java
@@ -26,14 +26,16 @@ import org.apache.syncope.common.lib.to.PrivilegeTO;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.ApplicationService;
 import org.apache.syncope.core.logic.ApplicationLogic;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
-public class ApplicationServiceImpl extends AbstractServiceImpl implements ApplicationService {
+public class ApplicationServiceImpl extends AbstractService implements ApplicationService {
 
-    @Autowired
-    private ApplicationLogic logic;
+    protected final ApplicationLogic logic;
+
+    public ApplicationServiceImpl(final ApplicationLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public List<ApplicationTO> list() {
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AuditServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AuditServiceImpl.java
index 998ee76..d094591 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AuditServiceImpl.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AuditServiceImpl.java
@@ -27,14 +27,16 @@ import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.rest.api.beans.AuditQuery;
 import org.apache.syncope.common.rest.api.service.AuditService;
 import org.apache.syncope.core.logic.AuditLogic;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
-public class AuditServiceImpl extends AbstractServiceImpl implements AuditService {
+public class AuditServiceImpl extends AbstractService implements AuditService {
 
-    @Autowired
-    private AuditLogic logic;
+    protected final AuditLogic logic;
+
+    public AuditServiceImpl(final AuditLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public List<AuditConfTO> list() {
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/DelegationServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/DelegationServiceImpl.java
index d6da13e..68465b1 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/DelegationServiceImpl.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/DelegationServiceImpl.java
@@ -25,14 +25,16 @@ import org.apache.syncope.common.lib.to.DelegationTO;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.DelegationService;
 import org.apache.syncope.core.logic.DelegationLogic;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
-public class DelegationServiceImpl extends AbstractServiceImpl implements DelegationService {
+public class DelegationServiceImpl extends AbstractService implements DelegationService {
 
-    @Autowired
-    private DelegationLogic logic;
+    protected final DelegationLogic logic;
+
+    public DelegationServiceImpl(final DelegationLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public List<DelegationTO> list() {
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/DynRealmServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/DynRealmServiceImpl.java
index 41e3bad..af3bdfa 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/DynRealmServiceImpl.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/DynRealmServiceImpl.java
@@ -25,14 +25,16 @@ import org.apache.syncope.common.lib.to.DynRealmTO;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.DynRealmService;
 import org.apache.syncope.core.logic.DynRealmLogic;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
-public class DynRealmServiceImpl extends AbstractServiceImpl implements DynRealmService {
+public class DynRealmServiceImpl extends AbstractService implements DynRealmService {
 
-    @Autowired
-    private DynRealmLogic logic;
+    protected final DynRealmLogic logic;
+
+    public DynRealmServiceImpl(final DynRealmLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public List<DynRealmTO> list() {
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java
index eedafba..391b2a1 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java
@@ -31,17 +31,25 @@ import org.apache.syncope.core.logic.AbstractAnyLogic;
 import org.apache.syncope.core.logic.GroupLogic;
 import org.apache.syncope.core.persistence.api.dao.AnyDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.syncope.core.persistence.api.search.SearchCondVisitor;
 import org.springframework.stereotype.Service;
 
 @Service
 public class GroupServiceImpl extends AbstractAnyService<GroupTO, GroupCR, GroupUR> implements GroupService {
 
-    @Autowired
-    private GroupDAO groupDAO;
+    protected final GroupDAO groupDAO;
 
-    @Autowired
-    private GroupLogic logic;
+    protected final GroupLogic logic;
+
+    public GroupServiceImpl(
+            final SearchCondVisitor searchCondVisitor,
+            final GroupDAO groupDAO,
+            final GroupLogic logic) {
+
+        super(searchCondVisitor);
+        this.groupDAO = groupDAO;
+        this.logic = logic;
+    }
 
     @Override
     protected AnyDAO<?> getAnyDAO() {
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ImplementationServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ImplementationServiceImpl.java
index d4db74d..fc99d12 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ImplementationServiceImpl.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ImplementationServiceImpl.java
@@ -25,14 +25,16 @@ import org.apache.syncope.common.lib.to.ImplementationTO;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.ImplementationService;
 import org.apache.syncope.core.logic.ImplementationLogic;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
-public class ImplementationServiceImpl extends AbstractServiceImpl implements ImplementationService {
+public class ImplementationServiceImpl extends AbstractService implements ImplementationService {
 
-    @Autowired
-    private ImplementationLogic logic;
+    protected final ImplementationLogic logic;
+
+    public ImplementationServiceImpl(final ImplementationLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public List<ImplementationTO> list(final String type) {
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/MailTemplateServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/MailTemplateServiceImpl.java
index 2c1a434..843b2ff 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/MailTemplateServiceImpl.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/MailTemplateServiceImpl.java
@@ -32,14 +32,16 @@ import org.apache.syncope.common.lib.types.MailTemplateFormat;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.MailTemplateService;
 import org.apache.syncope.core.logic.MailTemplateLogic;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
-public class MailTemplateServiceImpl extends AbstractServiceImpl implements MailTemplateService {
+public class MailTemplateServiceImpl extends AbstractService implements MailTemplateService {
 
-    @Autowired
-    private MailTemplateLogic logic;
+    protected final MailTemplateLogic logic;
+
+    public MailTemplateServiceImpl(final MailTemplateLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public Response create(final MailTemplateTO mailTemplateTO) {
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/NotificationServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/NotificationServiceImpl.java
index 874f138..3330273 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/NotificationServiceImpl.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/NotificationServiceImpl.java
@@ -27,14 +27,16 @@ import org.apache.syncope.common.lib.types.JobAction;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.NotificationService;
 import org.apache.syncope.core.logic.NotificationLogic;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
-public class NotificationServiceImpl extends AbstractServiceImpl implements NotificationService {
+public class NotificationServiceImpl extends AbstractService implements NotificationService {
 
-    @Autowired
-    private NotificationLogic logic;
+    protected final NotificationLogic logic;
+
+    public NotificationServiceImpl(final NotificationLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public Response create(final NotificationTO notificationTO) {
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/PolicyServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/PolicyServiceImpl.java
index 2616163..7280ab4 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/PolicyServiceImpl.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/PolicyServiceImpl.java
@@ -26,14 +26,16 @@ import org.apache.syncope.common.lib.types.PolicyType;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.PolicyService;
 import org.apache.syncope.core.logic.PolicyLogic;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
-public class PolicyServiceImpl extends AbstractServiceImpl implements PolicyService {
+public class PolicyServiceImpl extends AbstractService implements PolicyService {
 
-    @Autowired
-    private PolicyLogic logic;
+    protected final PolicyLogic logic;
+
+    public PolicyServiceImpl(final PolicyLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public Response create(final PolicyType type, final PolicyTO policyTO) {
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RealmServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RealmServiceImpl.java
index 7916a20..5bed0d6 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RealmServiceImpl.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RealmServiceImpl.java
@@ -31,14 +31,16 @@ import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.beans.RealmQuery;
 import org.apache.syncope.common.rest.api.service.RealmService;
 import org.apache.syncope.core.logic.RealmLogic;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
-public class RealmServiceImpl extends AbstractServiceImpl implements RealmService {
+public class RealmServiceImpl extends AbstractService implements RealmService {
 
-    @Autowired
-    private RealmLogic logic;
+    protected final RealmLogic logic;
+
+    public RealmServiceImpl(final RealmLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public PagedResult<RealmTO> search(final RealmQuery query) {
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RelationshipTypeServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RelationshipTypeServiceImpl.java
index 1cdc1d4..c30d8a5 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RelationshipTypeServiceImpl.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RelationshipTypeServiceImpl.java
@@ -25,14 +25,16 @@ import org.apache.syncope.common.lib.to.RelationshipTypeTO;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.RelationshipTypeService;
 import org.apache.syncope.core.logic.RelationshipTypeLogic;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
-public class RelationshipTypeServiceImpl extends AbstractServiceImpl implements RelationshipTypeService {
+public class RelationshipTypeServiceImpl extends AbstractService implements RelationshipTypeService {
 
-    @Autowired
-    private RelationshipTypeLogic logic;
+    protected final RelationshipTypeLogic logic;
+
+    public RelationshipTypeServiceImpl(final RelationshipTypeLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public List<RelationshipTypeTO> list() {
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReportServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReportServiceImpl.java
index e60994b..8f2de8b 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReportServiceImpl.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReportServiceImpl.java
@@ -32,14 +32,16 @@ import org.apache.syncope.common.rest.api.service.ReportService;
 import org.apache.syncope.core.logic.AbstractExecutableLogic;
 import org.apache.syncope.core.logic.ReportLogic;
 import org.apache.syncope.core.persistence.api.entity.ReportExec;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
 public class ReportServiceImpl extends AbstractExecutableService implements ReportService {
 
-    @Autowired
-    private ReportLogic logic;
+    protected final ReportLogic logic;
+
+    public ReportServiceImpl(final ReportLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     protected AbstractExecutableLogic<?> getExecutableLogic() {
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReportTemplateServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReportTemplateServiceImpl.java
index 9fc47d0..a90160b 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReportTemplateServiceImpl.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReportTemplateServiceImpl.java
@@ -33,14 +33,16 @@ import org.apache.syncope.common.lib.types.ReportTemplateFormat;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.ReportTemplateService;
 import org.apache.syncope.core.logic.ReportTemplateLogic;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
-public class ReportTemplateServiceImpl extends AbstractServiceImpl implements ReportTemplateService {
+public class ReportTemplateServiceImpl extends AbstractService implements ReportTemplateService {
 
-    @Autowired
-    private ReportTemplateLogic logic;
+    protected final ReportTemplateLogic logic;
+
+    public ReportTemplateServiceImpl(final ReportTemplateLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public Response create(final ReportTemplateTO reportTemplateTO) {
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RoleServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RoleServiceImpl.java
index 961ba63..6f610c2 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RoleServiceImpl.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RoleServiceImpl.java
@@ -32,14 +32,16 @@ import org.apache.syncope.common.lib.to.RoleTO;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.RoleService;
 import org.apache.syncope.core.logic.RoleLogic;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
-public class RoleServiceImpl extends AbstractServiceImpl implements RoleService {
+public class RoleServiceImpl extends AbstractService implements RoleService {
 
-    @Autowired
-    private RoleLogic logic;
+    protected final RoleLogic logic;
+
+    public RoleServiceImpl(final RoleLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public List<RoleTO> list() {
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SchemaServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SchemaServiceImpl.java
index dca79bf..2a4bd88 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SchemaServiceImpl.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SchemaServiceImpl.java
@@ -27,14 +27,16 @@ import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.beans.SchemaQuery;
 import org.apache.syncope.common.rest.api.service.SchemaService;
 import org.apache.syncope.core.logic.SchemaLogic;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
-public class SchemaServiceImpl extends AbstractServiceImpl implements SchemaService {
+public class SchemaServiceImpl extends AbstractService implements SchemaService {
 
-    @Autowired
-    private SchemaLogic logic;
+    protected final SchemaLogic logic;
+
+    public SchemaServiceImpl(final SchemaLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public Response create(final SchemaType schemaType, final SchemaTO schemaTO) {
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SecurityQuestionServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SecurityQuestionServiceImpl.java
index 5dca503..030cd6e 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SecurityQuestionServiceImpl.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SecurityQuestionServiceImpl.java
@@ -25,14 +25,16 @@ import org.apache.syncope.common.lib.to.SecurityQuestionTO;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.SecurityQuestionService;
 import org.apache.syncope.core.logic.SecurityQuestionLogic;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
-public class SecurityQuestionServiceImpl extends AbstractServiceImpl implements SecurityQuestionService {
+public class SecurityQuestionServiceImpl extends AbstractService implements SecurityQuestionService {
 
-    @Autowired
-    private SecurityQuestionLogic logic;
+    protected final SecurityQuestionLogic logic;
+
+    public SecurityQuestionServiceImpl(final SecurityQuestionLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     public List<SecurityQuestionTO> list() {
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SyncopeServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SyncopeServiceImpl.java
index 635c0c7..4d7c1e2 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SyncopeServiceImpl.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SyncopeServiceImpl.java
@@ -22,7 +22,6 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.util.Date;
 import java.util.List;
-import javax.annotation.Resource;
 import javax.ws.rs.InternalServerErrorException;
 import javax.ws.rs.NotFoundException;
 import javax.ws.rs.core.HttpHeaders;
@@ -48,7 +47,6 @@ import org.apache.syncope.common.rest.api.batch.BatchRequestItem;
 import org.apache.syncope.common.rest.api.service.SyncopeService;
 import org.apache.syncope.core.logic.SyncopeLogic;
 import org.apache.syncope.core.rest.cxf.batch.BatchProcess;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.apache.syncope.core.persistence.api.dao.BatchDAO;
 import org.apache.syncope.core.persistence.api.entity.Batch;
@@ -59,24 +57,33 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 import org.springframework.security.core.context.SecurityContextHolder;
 
 @Service
-public class SyncopeServiceImpl extends AbstractServiceImpl implements SyncopeService {
+public class SyncopeServiceImpl extends AbstractService implements SyncopeService {
 
     private static final String CONTENT_XML = "Content.xml";
 
-    @Resource(name = "batchExecutor")
-    private ThreadPoolTaskExecutor batchExecutor;
+    protected final SyncopeLogic logic;
 
-    @Autowired
-    private SyncopeLogic logic;
+    protected final ThreadPoolTaskExecutor batchExecutor;
 
-    @Autowired
-    private Bus bus;
+    protected final Bus bus;
 
-    @Autowired
-    private BatchDAO batchDAO;
+    protected final BatchDAO batchDAO;
 
-    @Autowired
-    private EntityFactory entityFactory;
+    protected final EntityFactory entityFactory;
+
+    public SyncopeServiceImpl(
+            final SyncopeLogic logic,
+            final ThreadPoolTaskExecutor batchExecutor,
+            final Bus bus,
+            final BatchDAO batchDAO,
+            final EntityFactory entityFactory) {
+
+        this.logic = logic;
+        this.batchExecutor = batchExecutor;
+        this.bus = bus;
+        this.batchDAO = batchDAO;
+        this.entityFactory = entityFactory;
+    }
 
     @Override
     public PagedResult<GroupTO> searchAssignableGroups(
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
index 6efb30f..9b32cb4 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
@@ -34,15 +34,17 @@ import org.apache.syncope.common.rest.api.beans.TaskQuery;
 import org.apache.syncope.common.rest.api.service.TaskService;
 import org.apache.syncope.core.logic.AbstractExecutableLogic;
 import org.apache.syncope.core.logic.TaskLogic;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
 @Service
 public class TaskServiceImpl extends AbstractExecutableService implements TaskService {
 
-    @Autowired
-    private TaskLogic logic;
+    protected final TaskLogic logic;
+
+    public TaskServiceImpl(final TaskLogic logic) {
+        this.logic = logic;
+    }
 
     @Override
     protected AbstractExecutableLogic<?> getExecutableLogic() {
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserSelfServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserSelfServiceImpl.java
index bd4176a..2c87276 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserSelfServiceImpl.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserSelfServiceImpl.java
@@ -32,17 +32,19 @@ import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.UserSelfService;
 import org.apache.syncope.core.logic.SyncopeLogic;
 import org.apache.syncope.core.logic.UserLogic;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
-public class UserSelfServiceImpl extends AbstractServiceImpl implements UserSelfService {
+public class UserSelfServiceImpl extends AbstractService implements UserSelfService {
 
-    @Autowired
-    private UserLogic logic;
+    protected final UserLogic logic;
 
-    @Autowired
-    private SyncopeLogic syncopeLogic;
+    protected final SyncopeLogic syncopeLogic;
+
+    public UserSelfServiceImpl(final UserLogic logic, final SyncopeLogic syncopeLogic) {
+        this.logic = logic;
+        this.syncopeLogic = syncopeLogic;
+    }
 
     @Override
     public Response create(final UserCR createReq) {
diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java
index 6daf501..4c51698 100644
--- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java
+++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java
@@ -30,17 +30,25 @@ import org.apache.syncope.core.logic.AbstractAnyLogic;
 import org.apache.syncope.core.logic.UserLogic;
 import org.apache.syncope.core.persistence.api.dao.AnyDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.syncope.core.persistence.api.search.SearchCondVisitor;
 import org.springframework.stereotype.Service;
 
 @Service
 public class UserServiceImpl extends AbstractAnyService<UserTO, UserCR, UserUR> implements UserService {
 
-    @Autowired
-    private UserDAO userDAO;
+    protected final UserDAO userDAO;
 
-    @Autowired
-    private UserLogic logic;
+    protected final UserLogic logic;
+
+    public UserServiceImpl(
+            final SearchCondVisitor searchCondVisitor,
+            final UserDAO userDAO,
+            final UserLogic logic) {
+
+        super(searchCondVisitor);
+        this.userDAO = userDAO;
+        this.logic = logic;
+    }
 
     @Override
     protected AnyDAO<?> getAnyDAO() {
diff --git a/core/idrepo/rest-cxf/src/main/resources/META-INF/spring.factories b/core/idrepo/rest-cxf/src/main/resources/META-INF/spring.factories
index 6864616..a9f7ef8 100644
--- a/core/idrepo/rest-cxf/src/main/resources/META-INF/spring.factories
+++ b/core/idrepo/rest-cxf/src/main/resources/META-INF/spring.factories
@@ -16,4 +16,4 @@
 # under the License.
 
 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-  org.apache.syncope.core.rest.cxf.RESTCXFContext
+  org.apache.syncope.core.rest.cxf.IdRepoRESTCXFContext
diff --git a/core/idrepo/rest-cxf/src/test/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceTest.java b/core/idrepo/rest-cxf/src/test/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceTest.java
index 5118cd9..2d30c95 100644
--- a/core/idrepo/rest-cxf/src/test/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceTest.java
+++ b/core/idrepo/rest-cxf/src/test/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceTest.java
@@ -86,7 +86,7 @@ import org.springframework.mock.web.MockHttpServletResponse;
 import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
 import org.springframework.test.util.ReflectionTestUtils;
 
-@SpringJUnitConfig(classes = { RESTCXFTestContext.class })
+@SpringJUnitConfig(classes = { IdRepoRESTCXFTestContext.class })
 public class AnyObjectServiceTest {
 
     private static final String LOCAL_ADDRESS = "local://anyObjects";
@@ -178,10 +178,7 @@ public class AnyObjectServiceTest {
             when(request.evaluatePreconditions(any(Date.class))).thenReturn(Response.notModified());
             when(messageContext.getRequest()).thenReturn(request);
 
-            AnyObjectServiceImpl service = new AnyObjectServiceImpl();
-            ReflectionTestUtils.setField(service, "anyObjectDAO", anyObjectDAO);
-            ReflectionTestUtils.setField(service, "logic", logic);
-            ReflectionTestUtils.setField(service, "searchCondVisitor", searchCondVisitor);
+            AnyObjectServiceImpl service = new AnyObjectServiceImpl(searchCondVisitor, anyObjectDAO, logic);
             ReflectionTestUtils.setField(service, "searchContext", searchContext);
             ReflectionTestUtils.setField(service, "uriInfo", uriInfo);
             ReflectionTestUtils.setField(service, "messageContext", messageContext);
diff --git a/core/idrepo/rest-cxf/src/test/java/org/apache/syncope/core/rest/cxf/service/RESTCXFTestContext.java b/core/idrepo/rest-cxf/src/test/java/org/apache/syncope/core/rest/cxf/service/IdRepoRESTCXFTestContext.java
similarity index 93%
rename from core/idrepo/rest-cxf/src/test/java/org/apache/syncope/core/rest/cxf/service/RESTCXFTestContext.java
rename to core/idrepo/rest-cxf/src/test/java/org/apache/syncope/core/rest/cxf/service/IdRepoRESTCXFTestContext.java
index 7195693..cd30151 100644
--- a/core/idrepo/rest-cxf/src/test/java/org/apache/syncope/core/rest/cxf/service/RESTCXFTestContext.java
+++ b/core/idrepo/rest-cxf/src/test/java/org/apache/syncope/core/rest/cxf/service/IdRepoRESTCXFTestContext.java
@@ -32,11 +32,16 @@ import org.apache.syncope.core.rest.cxf.RestServiceExceptionMapper;
 import org.apache.syncope.common.lib.jackson.SyncopeObjectMapper;
 import org.apache.syncope.common.lib.jackson.SyncopeXmlMapper;
 import org.apache.syncope.common.lib.jackson.SyncopeYAMLMapper;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.core.env.Environment;
 
 @Configuration
-public class RESTCXFTestContext {
+public class IdRepoRESTCXFTestContext {
+
+    @Autowired
+    private Environment env;
 
     @Bean
     public DateParamConverterProvider dateParamConverterProvider() {
@@ -91,7 +96,7 @@ public class RESTCXFTestContext {
 
     @Bean
     public RestServiceExceptionMapper restServiceExceptionMapper() {
-        return new RestServiceExceptionMapper();
+        return new RestServiceExceptionMapper(env);
     }
 
     @Bean
diff --git a/core/persistence-jpa-json/pom.xml b/core/persistence-jpa-json/pom.xml
index 68f7378..682630b 100644
--- a/core/persistence-jpa-json/pom.xml
+++ b/core/persistence-jpa-json/pom.xml
@@ -217,7 +217,7 @@ under the License.
 
     <profile>
       <id>pgjsonb</id>
-      
+
       <dependencies>
         <dependency>
           <groupId>org.postgresql</groupId>
@@ -266,6 +266,7 @@ under the License.
               </includes>
               <excludedGroups>multitenancy,plainAttrTable</excludedGroups>
               <systemProperties>
+                <profileId>${project.activeProfiles[0].id}</profileId>
                 <CORE_PROPERTIES>classpath:core-pgjsonb.properties,classpath:core-pgjsonb-test.properties</CORE_PROPERTIES>
                 <DB_CONTAINER_IP>${docker.container.postgres.ip}</DB_CONTAINER_IP>
               </systemProperties>
@@ -281,6 +282,7 @@ under the License.
                   <alias>postgres</alias>
                   <name>postgres:${docker.postgresql.version}</name>
                   <run>
+                    <cmd>postgres -N 200</cmd>
                     <env>
                       <POSTGRES_DB>syncope</POSTGRES_DB>
                       <POSTGRES_USER>syncope</POSTGRES_USER>
@@ -377,6 +379,7 @@ under the License.
               </includes>
               <excludedGroups>multitenancy,plainAttrTable</excludedGroups>
               <systemProperties>
+                <profileId>${project.activeProfiles[0].id}</profileId>
                 <CORE_PROPERTIES>classpath:core-myjson.properties,classpath:core-myjson-test.properties</CORE_PROPERTIES>
                 <DB_CONTAINER_IP>${docker.container.mysql.ip}</DB_CONTAINER_IP>
               </systemProperties>
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/JPAJSONPersistenceContext.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/JPAJSONPersistenceContext.java
new file mode 100644
index 0000000..b07658b
--- /dev/null
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/JPAJSONPersistenceContext.java
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa;
+
+import org.apache.syncope.core.persistence.api.dao.AccessTokenDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyMatchDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.DelegationDAO;
+import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.DynRealmDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.JPAJSONAnyDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainAttrValueDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.dao.RoleDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
+import org.apache.syncope.core.persistence.api.search.SearchCondVisitor;
+import org.apache.syncope.core.persistence.jpa.dao.JPAJSONAnyObjectDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPAJSONGroupDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPAJSONPlainAttrDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPAJSONPlainAttrValueDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPAJSONUserDAO;
+import org.apache.syncope.core.spring.security.SecurityProperties;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Lazy;
+
+@Configuration
+public abstract class JPAJSONPersistenceContext {
+
+    @Autowired
+    protected ApplicationEventPublisher publisher;
+
+    @Autowired
+    protected SecurityProperties securityProperties;
+
+    @ConditionalOnMissingBean(name = "jpaJSONAnyObjectDAO")
+    @Bean
+    @Autowired
+    public AnyObjectDAO anyObjectDAO(
+            final AnyUtilsFactory anyUtilsFactory,
+            final @Lazy PlainSchemaDAO plainSchemaDAO,
+            final @Lazy DerSchemaDAO derSchemaDAO,
+            final @Lazy DynRealmDAO dynRealmDAO,
+            final @Lazy UserDAO userDAO,
+            final @Lazy GroupDAO groupDAO,
+            final @Lazy JPAJSONAnyDAO anyDAO) {
+
+        return new JPAJSONAnyObjectDAO(
+                anyUtilsFactory,
+                publisher,
+                plainSchemaDAO,
+                derSchemaDAO,
+                dynRealmDAO,
+                userDAO,
+                groupDAO,
+                anyDAO);
+    }
+
+    @ConditionalOnMissingBean(name = "jpaJSONGroupDAO")
+    @Bean
+    @Autowired
+    public GroupDAO groupDAO(
+            final AnyUtilsFactory anyUtilsFactory,
+            final @Lazy PlainSchemaDAO plainSchemaDAO,
+            final @Lazy DerSchemaDAO derSchemaDAO,
+            final @Lazy DynRealmDAO dynRealmDAO,
+            final @Lazy AnyMatchDAO anyMatchDAO,
+            final @Lazy PlainAttrDAO plainAttrDAO,
+            final @Lazy UserDAO userDAO,
+            final @Lazy AnyObjectDAO anyObjectDAO,
+            final @Lazy AnySearchDAO anySearchDAO,
+            final SearchCondVisitor searchCondVisitor,
+            final @Lazy JPAJSONAnyDAO anyDAO) {
+
+        return new JPAJSONGroupDAO(
+                anyUtilsFactory,
+                publisher,
+                plainSchemaDAO,
+                derSchemaDAO,
+                dynRealmDAO,
+                anyMatchDAO,
+                plainAttrDAO,
+                userDAO,
+                anyObjectDAO,
+                anySearchDAO,
+                searchCondVisitor,
+                anyDAO);
+    }
+
+    @ConditionalOnMissingBean(name = "jpaJSONPlainAttrDAO")
+    @Bean
+    public PlainAttrDAO plainAttrDAO() {
+        return new JPAJSONPlainAttrDAO();
+    }
+
+    @ConditionalOnMissingBean(name = "jpaJSONPlainAttrValueDAO")
+    @Bean
+    public PlainAttrValueDAO plainAttrValueDAO() {
+        return new JPAJSONPlainAttrValueDAO();
+    }
+
+    @ConditionalOnMissingBean(name = "jpaJSONUserDAO")
+    @Bean
+    @Autowired
+    public UserDAO userDAO(
+            final AnyUtilsFactory anyUtilsFactory,
+            final @Lazy PlainSchemaDAO plainSchemaDAO,
+            final @Lazy DerSchemaDAO derSchemaDAO,
+            final @Lazy DynRealmDAO dynRealmDAO,
+            final @Lazy RoleDAO roleDAO,
+            final @Lazy AccessTokenDAO accessTokenDAO,
+            final @Lazy RealmDAO realmDAO,
+            final @Lazy GroupDAO groupDAO,
+            final @Lazy DelegationDAO delegationDAO,
+            final @Lazy JPAJSONAnyDAO anyDAO) {
+
+        return new JPAJSONUserDAO(
+                anyUtilsFactory,
+                publisher,
+                plainSchemaDAO,
+                derSchemaDAO,
+                dynRealmDAO,
+                roleDAO,
+                accessTokenDAO,
+                realmDAO,
+                groupDAO,
+                delegationDAO,
+                securityProperties,
+                anyDAO);
+    }
+}
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/MyJPAJSONPersistenceContext.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/MyJPAJSONPersistenceContext.java
new file mode 100644
index 0000000..49e4d63
--- /dev/null
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/MyJPAJSONPersistenceContext.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa;
+
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.AuditConfDAO;
+import org.apache.syncope.core.persistence.api.dao.DynRealmDAO;
+import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.JPAJSONAnyDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.jpa.dao.MyJPAJSONAnyDAO;
+import org.apache.syncope.core.persistence.jpa.dao.MyJPAJSONAnySearchDAO;
+import org.apache.syncope.core.persistence.jpa.dao.MyJPAJSONAuditConfDAO;
+import org.apache.syncope.core.persistence.jpa.dao.MyJPAJSONPlainSchemaDAO;
+import org.apache.syncope.core.persistence.jpa.entity.MyJPAJSONEntityFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Lazy;
+
+@ConditionalOnExpression("#{!('${provisioning.quartz.delegate}' matches '.*PostgreSQLDelegate.*')}")
+public class MyJPAJSONPersistenceContext extends JPAJSONPersistenceContext {
+
+    @ConditionalOnMissingBean(name = "myJPAJSONEntityFactory")
+    @Bean
+    public EntityFactory entityFactory() {
+        return new MyJPAJSONEntityFactory();
+    }
+
+    @ConditionalOnMissingBean(name = "myJPAJSONAnyDAO")
+    @Bean
+    @Autowired
+    public JPAJSONAnyDAO anyDAO(final PlainSchemaDAO plainSchemaDAO) {
+        return new MyJPAJSONAnyDAO(plainSchemaDAO);
+    }
+
+    @ConditionalOnMissingBean(name = "myJPAJSONAnySearchDAO")
+    @Bean
+    @Autowired
+    public AnySearchDAO anySearchDAO(
+            final @Lazy RealmDAO realmDAO,
+            final @Lazy DynRealmDAO dynRealmDAO,
+            final @Lazy UserDAO userDAO,
+            final @Lazy GroupDAO groupDAO,
+            final @Lazy AnyObjectDAO anyObjectDAO,
+            final @Lazy PlainSchemaDAO schemaDAO,
+            final @Lazy EntityFactory entityFactory,
+            final AnyUtilsFactory anyUtilsFactory) {
+
+        return new MyJPAJSONAnySearchDAO(
+                realmDAO,
+                dynRealmDAO,
+                userDAO,
+                groupDAO,
+                anyObjectDAO,
+                schemaDAO,
+                entityFactory,
+                anyUtilsFactory);
+    }
+
+    @ConditionalOnMissingBean(name = "myJPAJSONAuditConfDAO")
+    @Bean
+    public AuditConfDAO auditConfDAO() {
+        return new MyJPAJSONAuditConfDAO();
+    }
+
+    @ConditionalOnMissingBean(name = "myJPAJSONPlainSchemaDAO")
+    @Bean
+    @Autowired
+    public PlainSchemaDAO plainSchemaDAO(
+            final AnyUtilsFactory anyUtilsFactory,
+            final @Lazy PlainAttrDAO plainAttrDAO,
+            final @Lazy ExternalResourceDAO resourceDAO) {
+
+        return new MyJPAJSONPlainSchemaDAO(anyUtilsFactory, plainAttrDAO, resourceDAO);
+    }
+}
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/PGJPAJSONPersistenceContext.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/PGJPAJSONPersistenceContext.java
new file mode 100644
index 0000000..be63b58
--- /dev/null
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/PGJPAJSONPersistenceContext.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa;
+
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.AuditConfDAO;
+import org.apache.syncope.core.persistence.api.dao.DynRealmDAO;
+import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.JPAJSONAnyDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.jpa.dao.PGJPAJSONAnyDAO;
+import org.apache.syncope.core.persistence.jpa.dao.PGJPAJSONAnySearchDAO;
+import org.apache.syncope.core.persistence.jpa.dao.PGJPAJSONAuditConfDAO;
+import org.apache.syncope.core.persistence.jpa.dao.PGJPAJSONPlainSchemaDAO;
+import org.apache.syncope.core.persistence.jpa.entity.PGJPAJSONEntityFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Lazy;
+
+@ConditionalOnExpression("#{'${provisioning.quartz.delegate}' matches '.*PostgreSQLDelegate.*'}")
+public class PGJPAJSONPersistenceContext extends JPAJSONPersistenceContext {
+
+    @ConditionalOnMissingBean(name = "pgJPAJSONEntityFactory")
+    @Bean
+    public EntityFactory entityFactory() {
+        return new PGJPAJSONEntityFactory();
+    }
+
+    @ConditionalOnMissingBean(name = "pgJPAJSONAnyDAO")
+    @Bean
+    @Autowired
+    public JPAJSONAnyDAO anyDAO(final @Lazy PlainSchemaDAO plainSchemaDAO) {
+        return new PGJPAJSONAnyDAO(plainSchemaDAO);
+    }
+
+    @ConditionalOnMissingBean(name = "pgJPAJSONAnySearchDAO")
+    @Bean
+    @Autowired
+    public AnySearchDAO anySearchDAO(
+            final @Lazy RealmDAO realmDAO,
+            final @Lazy DynRealmDAO dynRealmDAO,
+            final @Lazy UserDAO userDAO,
+            final @Lazy GroupDAO groupDAO,
+            final @Lazy AnyObjectDAO anyObjectDAO,
+            final @Lazy PlainSchemaDAO plainSchemaDAO,
+            final @Lazy EntityFactory entityFactory,
+            final AnyUtilsFactory anyUtilsFactory) {
+
+        return new PGJPAJSONAnySearchDAO(
+                realmDAO,
+                dynRealmDAO,
+                userDAO,
+                groupDAO,
+                anyObjectDAO,
+                plainSchemaDAO,
+                entityFactory,
+                anyUtilsFactory);
+    }
+
+    @ConditionalOnMissingBean(name = "pgJPAJSONAuditConfDAO")
+    @Bean
+    public AuditConfDAO auditConfDAO() {
+        return new PGJPAJSONAuditConfDAO();
+    }
+
+    @ConditionalOnMissingBean(name = "pgJPAJSONPlainSchemaDAO")
+    @Bean
+    @Autowired
+    public PlainSchemaDAO plainSchemaDAO(
+            final AnyUtilsFactory anyUtilsFactory,
+            final @Lazy PlainAttrDAO plainAttrDAO,
+            final @Lazy ExternalResourceDAO resourceDAO) {
+
+        return new PGJPAJSONPlainSchemaDAO(anyUtilsFactory, plainAttrDAO, resourceDAO);
+    }
+}
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractJPAJSONAnyDAO.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractJPAJSONAnyDAO.java
index bb44c19..b4a1e01 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractJPAJSONAnyDAO.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractJPAJSONAnyDAO.java
@@ -48,13 +48,15 @@ import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractEntity;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 
 abstract class AbstractJPAJSONAnyDAO extends AbstractDAO<AbstractEntity> implements JPAJSONAnyDAO {
 
-    @Autowired
-    private PlainSchemaDAO plainSchemaDAO;
+    protected final PlainSchemaDAO plainSchemaDAO;
+
+    protected AbstractJPAJSONAnyDAO(final PlainSchemaDAO plainSchemaDAO) {
+        this.plainSchemaDAO = plainSchemaDAO;
+    }
 
     protected abstract String queryBegin(String table);
 
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractJPAJSONPlainSchemaDAO.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractJPAJSONPlainSchemaDAO.java
index 9034af0..d7beded 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractJPAJSONPlainSchemaDAO.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractJPAJSONPlainSchemaDAO.java
@@ -20,6 +20,9 @@ package org.apache.syncope.core.persistence.jpa.dao;
 
 import java.util.List;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr;
@@ -27,6 +30,14 @@ import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr;
 
 abstract class AbstractJPAJSONPlainSchemaDAO extends JPAPlainSchemaDAO {
 
+    protected AbstractJPAJSONPlainSchemaDAO(
+            final AnyUtilsFactory anyUtilsFactory,
+            final PlainAttrDAO plainAttrDAO,
+            final ExternalResourceDAO resourceDAO) {
+
+        super(anyUtilsFactory, plainAttrDAO, resourceDAO);
+    }
+
     @Override
     public <T extends PlainAttr<?>> List<T> findAttrs(final PlainSchema schema, final Class<T> reference) {
         // not possible
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJSONAnyObjectDAO.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJSONAnyObjectDAO.java
index 253f382..3850731 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJSONAnyObjectDAO.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJSONAnyObjectDAO.java
@@ -22,26 +22,39 @@ import java.util.List;
 import java.util.Optional;
 import java.util.Set;
 import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.DynRealmDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAJSONAnyObject;
-import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.dao.JPAJSONAnyDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.provisioning.api.event.AnyCreatedUpdatedEvent;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.springframework.context.ApplicationEventPublisher;
 
 public class JPAJSONAnyObjectDAO extends JPAAnyObjectDAO {
 
-    private JPAJSONAnyDAO anyDAO;
+    protected final JPAJSONAnyDAO anyDAO;
 
-    private JPAJSONAnyDAO anyDAO() {
-        if (anyDAO == null) {
-            anyDAO = ApplicationContextProvider.getApplicationContext().getBean(JPAJSONAnyDAO.class);
-        }
-        return anyDAO;
+    public JPAJSONAnyObjectDAO(
+            final AnyUtilsFactory anyUtilsFactory,
+            final ApplicationEventPublisher publisher,
+            final PlainSchemaDAO plainSchemaDAO,
+            final DerSchemaDAO derSchemaDAO,
+            final DynRealmDAO dynRealmDAO,
+            final UserDAO userDAO,
+            final GroupDAO groupDAO,
+            final JPAJSONAnyDAO anyDAO) {
+
+        super(anyUtilsFactory, publisher, plainSchemaDAO, derSchemaDAO, dynRealmDAO, userDAO, groupDAO);
+        this.anyDAO = anyDAO;
     }
 
     @Override
@@ -50,7 +63,7 @@ public class JPAJSONAnyObjectDAO extends JPAAnyObjectDAO {
             final PlainAttrValue attrValue,
             final boolean ignoreCaseMatch) {
 
-        return anyDAO().findByPlainAttrValue(
+        return anyDAO.findByPlainAttrValue(
                 JPAJSONAnyObject.TABLE, anyUtils(), schema, attrValue, ignoreCaseMatch);
     }
 
@@ -60,7 +73,7 @@ public class JPAJSONAnyObjectDAO extends JPAAnyObjectDAO {
             final PlainAttrUniqueValue attrUniqueValue,
             final boolean ignoreCaseMatch) {
 
-        return anyDAO().findByPlainAttrUniqueValue(
+        return anyDAO.findByPlainAttrUniqueValue(
                 JPAJSONAnyObject.TABLE, anyUtils(), schema, attrUniqueValue, ignoreCaseMatch);
     }
 
@@ -70,7 +83,7 @@ public class JPAJSONAnyObjectDAO extends JPAAnyObjectDAO {
             final String value,
             final boolean ignoreCaseMatch) {
 
-        return anyDAO().findByDerAttrValue(JPAJSONAnyObject.TABLE, anyUtils(), schema, value, ignoreCaseMatch);
+        return anyDAO.findByDerAttrValue(JPAJSONAnyObject.TABLE, anyUtils(), schema, value, ignoreCaseMatch);
     }
 
     @Override
@@ -90,7 +103,7 @@ public class JPAJSONAnyObjectDAO extends JPAAnyObjectDAO {
 
     @Override
     public AnyObject save(final AnyObject anyObject) {
-        anyDAO().checkBeforeSave(JPAJSONAnyObject.TABLE, anyUtils(), anyObject);
+        anyDAO.checkBeforeSave(JPAJSONAnyObject.TABLE, anyUtils(), anyObject);
         return super.save(anyObject);
     }
 }
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJSONGroupDAO.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJSONGroupDAO.java
index 7066cdd..1702103 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJSONGroupDAO.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJSONGroupDAO.java
@@ -20,24 +20,55 @@ package org.apache.syncope.core.persistence.jpa.dao;
 
 import java.util.List;
 import java.util.Optional;
+import org.apache.syncope.core.persistence.api.dao.AnyMatchDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.DynRealmDAO;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup;
-import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.dao.JPAJSONAnyDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
+import org.apache.syncope.core.persistence.api.search.SearchCondVisitor;
+import org.springframework.context.ApplicationEventPublisher;
 
 public class JPAJSONGroupDAO extends JPAGroupDAO {
 
-    private JPAJSONAnyDAO anyDAO;
+    protected final JPAJSONAnyDAO anyDAO;
 
-    private JPAJSONAnyDAO anyDAO() {
-        if (anyDAO == null) {
-            anyDAO = ApplicationContextProvider.getApplicationContext().getBean(JPAJSONAnyDAO.class);
-        }
-        return anyDAO;
+    public JPAJSONGroupDAO(
+            final AnyUtilsFactory anyUtilsFactory,
+            final ApplicationEventPublisher publisher,
+            final PlainSchemaDAO plainSchemaDAO,
+            final DerSchemaDAO derSchemaDAO,
+            final DynRealmDAO dynRealmDAO,
+            final AnyMatchDAO anyMatchDAO,
+            final PlainAttrDAO plainAttrDAO,
+            final UserDAO userDAO,
+            final AnyObjectDAO anyObjectDAO,
+            final AnySearchDAO searchDAO,
+            final SearchCondVisitor searchCondVisitor,
+            final JPAJSONAnyDAO anyDAO) {
+
+        super(anyUtilsFactory,
+                publisher,
+                plainSchemaDAO,
+                derSchemaDAO,
+                dynRealmDAO,
+                anyMatchDAO,
+                plainAttrDAO,
+                userDAO,
+                anyObjectDAO,
+                searchDAO,
+                searchCondVisitor);
+        this.anyDAO = anyDAO;
     }
 
     @Override
@@ -46,7 +77,7 @@ public class JPAJSONGroupDAO extends JPAGroupDAO {
             final PlainAttrValue attrValue,
             final boolean ignoreCaseMatch) {
 
-        return anyDAO().findByPlainAttrValue(
+        return anyDAO.findByPlainAttrValue(
                 JPAGroup.TABLE, anyUtils(), schema, attrValue, ignoreCaseMatch);
     }
 
@@ -56,7 +87,7 @@ public class JPAJSONGroupDAO extends JPAGroupDAO {
             final PlainAttrUniqueValue attrUniqueValue,
             final boolean ignoreCaseMatch) {
 
-        return anyDAO().findByPlainAttrUniqueValue(
+        return anyDAO.findByPlainAttrUniqueValue(
                 JPAGroup.TABLE, anyUtils(), schema, attrUniqueValue, ignoreCaseMatch);
     }
 
@@ -66,12 +97,12 @@ public class JPAJSONGroupDAO extends JPAGroupDAO {
             final String value,
             final boolean ignoreCaseMatch) {
 
-        return anyDAO().findByDerAttrValue(JPAGroup.TABLE, anyUtils(), schema, value, ignoreCaseMatch);
+        return anyDAO.findByDerAttrValue(JPAGroup.TABLE, anyUtils(), schema, value, ignoreCaseMatch);
     }
 
     @Override
     public Group save(final Group group) {
-        anyDAO().checkBeforeSave(JPAGroup.TABLE, anyUtils(), group);
+        anyDAO.checkBeforeSave(JPAGroup.TABLE, anyUtils(), group);
         return super.save(group);
     }
 }
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJSONUserDAO.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJSONUserDAO.java
index 345d1ef..1347ad6 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJSONUserDAO.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJSONUserDAO.java
@@ -23,27 +23,58 @@ import java.util.Optional;
 import java.util.Set;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
+import org.apache.syncope.core.persistence.api.dao.AccessTokenDAO;
+import org.apache.syncope.core.persistence.api.dao.DelegationDAO;
+import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.DynRealmDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAJSONUser;
-import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.dao.JPAJSONAnyDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.dao.RoleDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
 import org.apache.syncope.core.provisioning.api.event.AnyCreatedUpdatedEvent;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.SecurityProperties;
+import org.springframework.context.ApplicationEventPublisher;
 
 public class JPAJSONUserDAO extends JPAUserDAO {
 
-    private JPAJSONAnyDAO anyDAO;
-
-    private JPAJSONAnyDAO anyDAO() {
-        if (anyDAO == null) {
-            anyDAO = ApplicationContextProvider.getApplicationContext().getBean(JPAJSONAnyDAO.class);
-        }
-        return anyDAO;
+    protected final JPAJSONAnyDAO anyDAO;
+
+    public JPAJSONUserDAO(
+            final AnyUtilsFactory anyUtilsFactory,
+            final ApplicationEventPublisher publisher,
+            final PlainSchemaDAO plainSchemaDAO,
+            final DerSchemaDAO derSchemaDAO,
+            final DynRealmDAO dynRealmDAO,
+            final RoleDAO roleDAO,
+            final AccessTokenDAO accessTokenDAO,
+            final RealmDAO realmDAO,
+            final GroupDAO groupDAO,
+            final DelegationDAO delegationDAO,
+            final SecurityProperties securityProperties,
+            final JPAJSONAnyDAO anyDAO) {
+
+        super(anyUtilsFactory,
+                publisher,
+                plainSchemaDAO,
+                derSchemaDAO,
+                dynRealmDAO,
+                roleDAO,
+                accessTokenDAO,
+                realmDAO,
+                groupDAO,
+                delegationDAO,
+                securityProperties);
+        this.anyDAO = anyDAO;
     }
 
     @Override
@@ -52,7 +83,7 @@ public class JPAJSONUserDAO extends JPAUserDAO {
             final PlainAttrValue attrValue,
             final boolean ignoreCaseMatch) {
 
-        return anyDAO().findByPlainAttrValue(
+        return anyDAO.findByPlainAttrValue(
                 JPAJSONUser.TABLE, anyUtils(), schema, attrValue, ignoreCaseMatch);
     }
 
@@ -62,7 +93,7 @@ public class JPAJSONUserDAO extends JPAUserDAO {
             final PlainAttrUniqueValue attrUniqueValue,
             final boolean ignoreCaseMatch) {
 
-        return anyDAO().findByPlainAttrUniqueValue(
+        return anyDAO.findByPlainAttrUniqueValue(
                 JPAJSONUser.TABLE, anyUtils(), schema, attrUniqueValue, ignoreCaseMatch);
     }
 
@@ -72,7 +103,7 @@ public class JPAJSONUserDAO extends JPAUserDAO {
             final String value,
             final boolean ignoreCaseMatch) {
 
-        return anyDAO().findByDerAttrValue(JPAJSONUser.TABLE, anyUtils(), schema, value, ignoreCaseMatch);
+        return anyDAO.findByDerAttrValue(JPAJSONUser.TABLE, anyUtils(), schema, value, ignoreCaseMatch);
     }
 
     @Override
@@ -108,13 +139,13 @@ public class JPAJSONUserDAO extends JPAUserDAO {
 
     @Override
     public User save(final User user) {
-        anyDAO().checkBeforeSave(JPAJSONUser.TABLE, anyUtils(), user);
+        anyDAO.checkBeforeSave(JPAJSONUser.TABLE, anyUtils(), user);
         return super.save(user);
     }
 
     @Override
     public Pair<Set<String>, Set<String>> saveAndGetDynGroupMembs(final User user) {
-        anyDAO().checkBeforeSave(JPAJSONUser.TABLE, anyUtils(), user);
+        anyDAO.checkBeforeSave(JPAJSONUser.TABLE, anyUtils(), user);
         return super.saveAndGetDynGroupMembs(user);
     }
 }
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAnyDAO.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAnyDAO.java
index 6e1486b..5555811 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAnyDAO.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAnyDAO.java
@@ -22,6 +22,7 @@ import java.util.List;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
 import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue;
@@ -32,6 +33,10 @@ import org.apache.syncope.core.persistence.api.entity.JSONPlainAttr;
 
 public class MyJPAJSONAnyDAO extends AbstractJPAJSONAnyDAO {
 
+    public MyJPAJSONAnyDAO(final PlainSchemaDAO plainSchemaDAO) {
+        super(plainSchemaDAO);
+    }
+
     @Override
     protected String queryBegin(final String table) {
         String view = StringUtils.containsIgnoreCase(table, AnyTypeKind.USER.name())
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAnySearchDAO.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAnySearchDAO.java
index 3900d9f..d3a83a9 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAnySearchDAO.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAnySearchDAO.java
@@ -24,10 +24,18 @@ import java.util.Set;
 import java.util.stream.Collectors;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.DynRealmDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
 import org.apache.syncope.core.persistence.api.dao.search.AttrCond;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
@@ -37,6 +45,19 @@ import org.apache.syncope.core.persistence.api.entity.JSONPlainAttr;
 
 public class MyJPAJSONAnySearchDAO extends JPAAnySearchDAO {
 
+    public MyJPAJSONAnySearchDAO(
+            final RealmDAO realmDAO,
+            final DynRealmDAO dynRealmDAO,
+            final UserDAO userDAO,
+            final GroupDAO groupDAO,
+            final AnyObjectDAO anyObjectDAO,
+            final PlainSchemaDAO schemaDAO,
+            final EntityFactory entityFactory,
+            final AnyUtilsFactory anyUtilsFactory) {
+
+        super(realmDAO, dynRealmDAO, userDAO, groupDAO, anyObjectDAO, schemaDAO, entityFactory, anyUtilsFactory);
+    }
+
     @Override
     protected void processOBS(
             final SearchSupport svs,
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONPlainSchemaDAO.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONPlainSchemaDAO.java
index 81bce44..3e1d642 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONPlainSchemaDAO.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONPlainSchemaDAO.java
@@ -19,11 +19,22 @@
 package org.apache.syncope.core.persistence.jpa.dao;
 
 import javax.persistence.Query;
+import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 
 public class MyJPAJSONPlainSchemaDAO extends AbstractJPAJSONPlainSchemaDAO {
 
+    public MyJPAJSONPlainSchemaDAO(
+            final AnyUtilsFactory anyUtilsFactory,
+            final PlainAttrDAO plainAttrDAO,
+            final ExternalResourceDAO resourceDAO) {
+
+        super(anyUtilsFactory, plainAttrDAO, resourceDAO);
+    }
+
     @Override
     public <T extends PlainAttr<?>> boolean hasAttrs(final PlainSchema schema, final Class<T> reference) {
         Query query = entityManager().createNativeQuery(
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnyDAO.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnyDAO.java
index 56df7a5..1a32d6a 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnyDAO.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnyDAO.java
@@ -20,6 +20,7 @@ package org.apache.syncope.core.persistence.jpa.dao;
 
 import java.util.List;
 import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
 import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue;
@@ -30,6 +31,10 @@ import org.apache.syncope.core.persistence.api.entity.JSONPlainAttr;
 
 public class PGJPAJSONAnyDAO extends AbstractJPAJSONAnyDAO {
 
+    public PGJPAJSONAnyDAO(final PlainSchemaDAO plainSchemaDAO) {
+        super(plainSchemaDAO);
+    }
+
     @Override
     protected String queryBegin(final String table) {
         return "SELECT DISTINCT id FROM " + table + " u,"
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnySearchDAO.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnySearchDAO.java
index 3b96a56..59b1780 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnySearchDAO.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnySearchDAO.java
@@ -30,6 +30,12 @@ import org.apache.commons.lang3.tuple.Triple;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.DynRealmDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
 import org.apache.syncope.core.persistence.api.dao.search.AnyTypeCond;
 import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
@@ -46,6 +52,8 @@ import org.apache.syncope.core.persistence.api.dao.search.RoleCond;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.Realm;
@@ -64,6 +72,19 @@ public class PGJPAJSONAnySearchDAO extends JPAAnySearchDAO {
         return output;
     }
 
+    public PGJPAJSONAnySearchDAO(
+            final RealmDAO realmDAO,
+            final DynRealmDAO dynRealmDAO,
+            final UserDAO userDAO,
+            final GroupDAO groupDAO,
+            final AnyObjectDAO anyObjectDAO,
+            final PlainSchemaDAO plainSchemaDAO,
+            final EntityFactory entityFactory,
+            final AnyUtilsFactory anyUtilsFactory) {
+
+        super(realmDAO, dynRealmDAO, userDAO, groupDAO, anyObjectDAO, plainSchemaDAO, entityFactory, anyUtilsFactory);
+    }
+
     @Override
     protected void parseOrderByForPlainSchema(
             final SearchSupport svs,
@@ -603,7 +624,7 @@ public class PGJPAJSONAnySearchDAO extends JPAAnySearchDAO {
 
         StringBuilder query = new StringBuilder();
 
-        PlainSchema schema = schemaDAO.find(cond.getSchema());
+        PlainSchema schema = plainSchemaDAO.find(cond.getSchema());
         if (schema == null) {
             fillAttrQuery(query, checked.getMiddle(), checked.getLeft(), checked.getRight(), not, parameters, svs);
         } else {
@@ -864,7 +885,7 @@ public class PGJPAJSONAnySearchDAO extends JPAAnySearchDAO {
 
         schemas.forEach(schema -> {
             // i.e jsonb_path_query(plainattrs, '$[*] ? (@.schema=="Nome")."values"') AS Nome
-            PlainSchema pschema = schemaDAO.find(schema);
+            PlainSchema pschema = plainSchemaDAO.find(schema);
             if (pschema == null) {
                 // just to be sure
                 LOG.warn("Ignoring invalid schema '{}'", schema);
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONPlainSchemaDAO.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONPlainSchemaDAO.java
index e9ad63f..5f729e8 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONPlainSchemaDAO.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONPlainSchemaDAO.java
@@ -19,11 +19,22 @@
 package org.apache.syncope.core.persistence.jpa.dao;
 
 import javax.persistence.Query;
+import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 
 public class PGJPAJSONPlainSchemaDAO extends AbstractJPAJSONPlainSchemaDAO {
 
+    public PGJPAJSONPlainSchemaDAO(
+            final AnyUtilsFactory anyUtilsFactory,
+            final PlainAttrDAO plainAttrDAO,
+            final ExternalResourceDAO resourceDAO) {
+
+        super(anyUtilsFactory, plainAttrDAO, resourceDAO);
+    }
+
     @Override
     public <T extends PlainAttr<?>> boolean hasAttrs(final PlainSchema schema, final Class<T> reference) {
         Query query = entityManager().createNativeQuery(
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAJSONEntityFactory.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAJSONEntityFactory.java
index 96ef097..078f5ab 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAJSONEntityFactory.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAJSONEntityFactory.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.core.persistence.jpa.entity;
 
-import org.apache.syncope.core.persistence.api.dao.JPAJSONAnyDAO;
 import org.apache.syncope.core.persistence.api.entity.Entity;
 import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr;
 import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrUniqueValue;
@@ -53,18 +52,11 @@ import org.apache.syncope.core.persistence.jpa.entity.user.JPAJSONUPlainAttr;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAJSONUPlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAJSONUPlainAttrValue;
 import org.apache.syncope.core.spring.security.SecureRandomUtils;
-import org.springframework.beans.factory.BeanFactory;
-import org.springframework.beans.factory.BeanFactoryAware;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.beans.factory.support.AbstractBeanDefinition;
-import org.springframework.beans.factory.support.DefaultListableBeanFactory;
 
-public abstract class JPAJSONEntityFactory extends JPAEntityFactory implements InitializingBean, BeanFactoryAware {
+public abstract class JPAJSONEntityFactory extends JPAEntityFactory {
 
-    private DefaultListableBeanFactory beanFactory;
-
-    @Override
     @SuppressWarnings("unchecked")
+    @Override
     public <E extends Entity> E newEntity(final Class<E> reference) {
         E result;
 
@@ -125,17 +117,4 @@ public abstract class JPAJSONEntityFactory extends JPAEntityFactory implements I
     public Class<? extends AnyObject> anyObjectClass() {
         return JPAJSONAnyObject.class;
     }
-
-    protected abstract Class<? extends JPAJSONAnyDAO> jpaJSONAnyDAOClass();
-
-    @Override
-    public void setBeanFactory(final BeanFactory beanFactory) {
-        this.beanFactory = (DefaultListableBeanFactory) beanFactory;
-    }
-
-    @Override
-    public void afterPropertiesSet() throws Exception {
-        beanFactory.registerSingleton("jpaJSONAnyDAO",
-                beanFactory.createBean(jpaJSONAnyDAOClass(), AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false));
-    }
 }
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/MyJPAJSONEntityFactory.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/MyJPAJSONEntityFactory.java
index ca17f7b..3429d47 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/MyJPAJSONEntityFactory.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/MyJPAJSONEntityFactory.java
@@ -19,8 +19,6 @@
 package org.apache.syncope.core.persistence.jpa.entity;
 
 import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
-import org.apache.syncope.core.persistence.api.dao.JPAJSONAnyDAO;
-import org.apache.syncope.core.persistence.jpa.dao.MyJPAJSONAnyDAO;
 import org.apache.syncope.core.persistence.jpa.dao.MyJPAJSONAnySearchDAO;
 
 public class MyJPAJSONEntityFactory extends JPAJSONEntityFactory {
@@ -29,9 +27,4 @@ public class MyJPAJSONEntityFactory extends JPAJSONEntityFactory {
     public Class<? extends AnySearchDAO> anySearchDAOClass() {
         return MyJPAJSONAnySearchDAO.class;
     }
-
-    @Override
-    protected Class<? extends JPAJSONAnyDAO> jpaJSONAnyDAOClass() {
-        return MyJPAJSONAnyDAO.class;
-    }
 }
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/PGJPAJSONEntityFactory.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/PGJPAJSONEntityFactory.java
index 998fc73..9da2e9e 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/PGJPAJSONEntityFactory.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/PGJPAJSONEntityFactory.java
@@ -19,8 +19,6 @@
 package org.apache.syncope.core.persistence.jpa.entity;
 
 import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
-import org.apache.syncope.core.persistence.api.dao.JPAJSONAnyDAO;
-import org.apache.syncope.core.persistence.jpa.dao.PGJPAJSONAnyDAO;
 import org.apache.syncope.core.persistence.jpa.dao.PGJPAJSONAnySearchDAO;
 
 public class PGJPAJSONEntityFactory extends JPAJSONEntityFactory {
@@ -29,9 +27,4 @@ public class PGJPAJSONEntityFactory extends JPAJSONEntityFactory {
     public Class<? extends AnySearchDAO> anySearchDAOClass() {
         return PGJPAJSONAnySearchDAO.class;
     }
-
-    @Override
-    protected Class<? extends JPAJSONAnyDAO> jpaJSONAnyDAOClass() {
-        return PGJPAJSONAnyDAO.class;
-    }
 }
diff --git a/ext/camel/provisioning-camel/src/main/resources/META-INF/spring.factories b/core/persistence-jpa-json/src/main/resources/META-INF/spring.factories
similarity index 86%
copy from ext/camel/provisioning-camel/src/main/resources/META-INF/spring.factories
copy to core/persistence-jpa-json/src/main/resources/META-INF/spring.factories
index a035d84..c43e216 100644
--- a/ext/camel/provisioning-camel/src/main/resources/META-INF/spring.factories
+++ b/core/persistence-jpa-json/src/main/resources/META-INF/spring.factories
@@ -16,4 +16,5 @@
 # under the License.
 
 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-  org.apache.syncope.core.provisioning.camel.ProvisioningCamelContext
+  org.apache.syncope.core.persistence.jpa.PGJPAJSONPersistenceContext,\
+  org.apache.syncope.core.persistence.jpa.MyJPAJSONPersistenceContext
diff --git a/core/persistence-jpa-json/src/main/resources/core-myjson.properties b/core/persistence-jpa-json/src/main/resources/core-myjson.properties
index 3899035..997eaed 100644
--- a/core/persistence-jpa-json/src/main/resources/core-myjson.properties
+++ b/core/persistence-jpa-json/src/main/resources/core-myjson.properties
@@ -15,20 +15,6 @@
 # specific language governing permissions and limitations
 # under the License.
 
-provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
-provisioning.quartz.sql=tables_mysql_innodb.sql
-
-persistence.entityFactory=org.apache.syncope.core.persistence.jpa.entity.MyJPAJSONEntityFactory
-persistence.plainSchemaDao=org.apache.syncope.core.persistence.jpa.dao.MyJPAJSONPlainSchemaDAO
-persistence.plainAttrDao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONPlainAttrDAO
-persistence.plainAttrValueDao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONPlainAttrValueDAO
-persistence.anySearchDao=org.apache.syncope.core.persistence.jpa.dao.MyJPAJSONAnySearchDAO
-persistence.searchCondVisitor=org.apache.syncope.core.persistence.api.search.SearchCondVisitor
-persistence.userDao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONUserDAO
-persistence.groupDao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONGroupDAO
-persistence.anyObjectDao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONAnyObjectDAO
-persistence.auditConfDao=org.apache.syncope.core.persistence.jpa.dao.MyJPAJSONAuditConfDAO
-
 persistence.indexesXML=classpath:myjson/indexes.xml
 persistence.viewsXML=classpath:myjson/views.xml
 
diff --git a/core/persistence-jpa-json/src/main/resources/core-pgjsonb.properties b/core/persistence-jpa-json/src/main/resources/core-pgjsonb.properties
index fe9154c..8a75349 100644
--- a/core/persistence-jpa-json/src/main/resources/core-pgjsonb.properties
+++ b/core/persistence-jpa-json/src/main/resources/core-pgjsonb.properties
@@ -15,17 +15,6 @@
 # specific language governing permissions and limitations
 # under the License.
 
-persistence.entityFactory=org.apache.syncope.core.persistence.jpa.entity.PGJPAJSONEntityFactory
-persistence.plainSchemaDao=org.apache.syncope.core.persistence.jpa.dao.PGJPAJSONPlainSchemaDAO
-persistence.plainAttrDao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONPlainAttrDAO
-persistence.plainAttrValueDao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONPlainAttrValueDAO
-persistence.anySearchDao=org.apache.syncope.core.persistence.jpa.dao.PGJPAJSONAnySearchDAO
-persistence.searchCondVisitor=org.apache.syncope.core.persistence.api.search.SearchCondVisitor
-persistence.userDao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONUserDAO
-persistence.groupDao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONGroupDAO
-persistence.anyObjectDao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONAnyObjectDAO
-persistence.auditConfDao=org.apache.syncope.core.persistence.jpa.dao.PGJPAJSONAuditConfDAO
-
 persistence.indexesXML=classpath:pgjsonb/indexes.xml
 persistence.viewsXML=classpath:pgjsonb/views.xml
 
diff --git a/core/persistence-jpa-json/src/test/java/org/apache/syncope/core/persistence/jpa/JPAJSONTestContextCustomizer.java b/core/persistence-jpa-json/src/test/java/org/apache/syncope/core/persistence/jpa/JPAJSONTestContextCustomizer.java
new file mode 100644
index 0000000..8700e31
--- /dev/null
+++ b/core/persistence-jpa-json/src/test/java/org/apache/syncope/core/persistence/jpa/JPAJSONTestContextCustomizer.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa;
+
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
+import org.springframework.context.support.AbstractApplicationContext;
+import org.springframework.test.context.ContextCustomizer;
+import org.springframework.test.context.MergedContextConfiguration;
+import org.springframework.test.context.support.TestPropertySourceUtils;
+
+public class JPAJSONTestContextCustomizer implements ContextCustomizer {
+
+    private static BeanDefinitionRegistry getBeanDefinitionRegistry(final ApplicationContext ctx) {
+        if (ctx instanceof BeanDefinitionRegistry) {
+            return (BeanDefinitionRegistry) ctx;
+        }
+        if (ctx instanceof AbstractApplicationContext) {
+            return (BeanDefinitionRegistry) ((AbstractApplicationContext) ctx).getBeanFactory();
+        }
+        throw new IllegalStateException("Could not locate BeanDefinitionRegistry");
+    }
+
+    @Override
+    public void customizeContext(final ConfigurableApplicationContext ctx, final MergedContextConfiguration cfg) {
+        if ("pgjsonb".equals(System.getProperty("profileId"))) {
+            TestPropertySourceUtils.addInlinedPropertiesToEnvironment(
+                    ctx,
+                    "provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate");
+        } else if ("myjson".equals(System.getProperty("profileId"))) {
+            TestPropertySourceUtils.addInlinedPropertiesToEnvironment(
+                    ctx,
+                    "provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.StdJDBCDelegate");
+        }
+
+        AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(getBeanDefinitionRegistry(ctx));
+        reader.registerBean(PGJPAJSONPersistenceContext.class, "PGJPAJSONPersistenceContext");
+        reader.registerBean(MyJPAJSONPersistenceContext.class, "MyJPAJSONPersistenceContext");
+    }
+}
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/DummyConnectorRegistry.java b/core/persistence-jpa-json/src/test/java/org/apache/syncope/core/persistence/jpa/JPAJSONTestContextCustomizerFactory.java
similarity index 62%
rename from core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/DummyConnectorRegistry.java
rename to core/persistence-jpa-json/src/test/java/org/apache/syncope/core/persistence/jpa/JPAJSONTestContextCustomizerFactory.java
index f0b892b..6738f88 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/DummyConnectorRegistry.java
+++ b/core/persistence-jpa-json/src/test/java/org/apache/syncope/core/persistence/jpa/JPAJSONTestContextCustomizerFactory.java
@@ -18,19 +18,18 @@
  */
 package org.apache.syncope.core.persistence.jpa;
 
-import org.apache.syncope.core.persistence.api.dao.NotFoundException;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-import org.apache.syncope.core.provisioning.api.ConnectorRegistry;
-import org.springframework.stereotype.Component;
+import java.util.List;
+import org.springframework.test.context.ContextConfigurationAttributes;
+import org.springframework.test.context.ContextCustomizer;
+import org.springframework.test.context.ContextCustomizerFactory;
 
-@Component
-public class DummyConnectorRegistry implements ConnectorRegistry {
+public class JPAJSONTestContextCustomizerFactory implements ContextCustomizerFactory {
 
     @Override
-    public void registerConnector(final ExternalResource resource) throws NotFoundException {
-    }
+    public ContextCustomizer createContextCustomizer(
+            final Class<?> testClass,
+            final List<ContextConfigurationAttributes> configAttributes) {
 
-    @Override
-    public void unregisterConnector(final String id) {
+        return new JPAJSONTestContextCustomizer();
     }
 }
diff --git a/ext/saml2sp4ui/logic/src/main/resources/META-INF/spring.factories b/core/persistence-jpa-json/src/test/resources/META-INF/spring.factories
similarity index 85%
copy from ext/saml2sp4ui/logic/src/main/resources/META-INF/spring.factories
copy to core/persistence-jpa-json/src/test/resources/META-INF/spring.factories
index 6cb5b1c..3131eed 100644
--- a/ext/saml2sp4ui/logic/src/main/resources/META-INF/spring.factories
+++ b/core/persistence-jpa-json/src/test/resources/META-INF/spring.factories
@@ -15,5 +15,5 @@
 # specific language governing permissions and limitations
 # under the License.
 
-org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-  org.apache.syncope.core.logic.SAML2SP4UIContext
+org.springframework.test.context.ContextCustomizerFactory=\
+  org.apache.syncope.core.persistence.jpa.JPAJSONTestContextCustomizerFactory
diff --git a/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml
index bf0e75a..698faf4 100644
--- a/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml
@@ -143,7 +143,7 @@ under the License.
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
   <SchemaLabel id="d90f90d0-cf15-407e-bac7-d46a8eb57c05" schema_id="firstname" locale="en" display="Firstname"/>
   <SchemaLabel id="a9465ef0-b8b4-4af4-840d-77031a6b54a0" schema_id="firstname" locale="it" display="Nome"/>
-  <SchemaLabel id="ac8b7383-62df-490d-9364-88dbd3d301aa" schema_id="firstname" locale="pt_BR" display="Nome prĂłprio"/>
+  <SchemaLabel id="ac8b7383-62df-490d-9364-88dbd3d301aa" schema_id="firstname" locale="pt_BR" display="Nome"/>
   <SyncopeSchema id="surname"/>
   <PlainSchema id="surname" type="String" anyTypeClass_id="minimal user"
                mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
diff --git a/core/persistence-jpa-json/src/test/resources/simplelogger.properties b/core/persistence-jpa-json/src/test/resources/simplelogger.properties
index 929ded2..4f528c6 100644
--- a/core/persistence-jpa-json/src/test/resources/simplelogger.properties
+++ b/core/persistence-jpa-json/src/test/resources/simplelogger.properties
@@ -19,4 +19,3 @@
 # Possible values: "trace", "debug", "info", "warn", or "error"
 org.slf4j.simpleLogger.defaultLogLevel=debug
 org.slf4j.simpleLogger.log.org.springframework.jdbc.core.JdbcTemplate=error
-
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/DomainConfFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/DomainConfFactory.java
index a596eeb..bf79683 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/DomainConfFactory.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/DomainConfFactory.java
@@ -37,7 +37,6 @@ import org.springframework.beans.factory.config.BeanDefinition;
 import org.springframework.beans.factory.support.AbstractBeanDefinition;
 import org.springframework.beans.factory.support.AutowireCandidateQualifier;
 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.context.EnvironmentAware;
 import org.springframework.core.env.Environment;
 import org.springframework.core.io.ClassPathResource;
 import org.springframework.jdbc.datasource.init.DataSourceInitializer;
@@ -45,42 +44,39 @@ import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
 import org.springframework.jndi.JndiObjectFactoryBean;
 import org.springframework.orm.jpa.JpaTransactionManager;
 import org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter;
-import org.springframework.stereotype.Component;
 
-@Component
-public class DomainConfFactory implements DomainRegistry, EnvironmentAware {
+public class DomainConfFactory implements DomainRegistry {
 
-    private static final Logger LOG = LoggerFactory.getLogger(DomainConfFactory.class);
+    protected static final Logger LOG = LoggerFactory.getLogger(DomainConfFactory.class);
 
-    private Environment env;
-
-    @Override
-    public void setEnvironment(final Environment env) {
-        this.env = env;
-    }
-
-    private static void unregisterSingleton(final String name) {
+    protected static void unregisterSingleton(final String name) {
         if (ApplicationContextProvider.getBeanFactory().containsSingleton(name)) {
             ApplicationContextProvider.getBeanFactory().destroySingleton(name);
         }
     }
 
-    private static void registerSingleton(final String name, final Object bean) {
+    protected static void registerSingleton(final String name, final Object bean) {
         unregisterSingleton(name);
         ApplicationContextProvider.getBeanFactory().registerSingleton(name, bean);
     }
 
-    private static void unregisterBeanDefinition(final String name) {
+    protected static void unregisterBeanDefinition(final String name) {
         if (ApplicationContextProvider.getBeanFactory().containsBeanDefinition(name)) {
             ApplicationContextProvider.getBeanFactory().removeBeanDefinition(name);
         }
     }
 
-    private static void registerBeanDefinition(final String name, final BeanDefinition beanDefinition) {
+    protected static void registerBeanDefinition(final String name, final BeanDefinition beanDefinition) {
         unregisterBeanDefinition(name);
         ApplicationContextProvider.getBeanFactory().registerBeanDefinition(name, beanDefinition);
     }
 
+    protected final Environment env;
+
+    public DomainConfFactory(final Environment env) {
+        this.env = env;
+    }
+
     @Override
     public void register(final Domain domain) {
         HikariConfig hikariConfig = new HikariConfig();
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/MasterDomain.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/MasterDomain.java
index 215bb9f..0049087 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/MasterDomain.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/MasterDomain.java
@@ -75,24 +75,19 @@ public class MasterDomain {
         return masterDataSource;
     }
 
-    @ConditionalOnMissingBean(name = "MasterResourceDatabasePopulator")
-    @Bean(name = "MasterResourceDatabasePopulator")
-    public ResourceDatabasePopulator masterResourceDatabasePopulator() {
+    @ConditionalOnMissingBean(name = "MasterDataSourceInitializer")
+    @Bean(name = "MasterDataSourceInitializer")
+    public DataSourceInitializer masterDataSourceInitializer() {
         ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator();
         databasePopulator.setContinueOnError(true);
         databasePopulator.setIgnoreFailedDrops(true);
         databasePopulator.setSqlScriptEncoding("UTF-8");
         databasePopulator.addScript(new ClassPathResource("/audit/" + props.getDomain().get(0).getAuditSql()));
-        return databasePopulator;
-    }
 
-    @ConditionalOnMissingBean(name = "MasterDataSourceInitializer")
-    @Bean(name = "MasterDataSourceInitializer")
-    public DataSourceInitializer masterDataSourceInitializer() {
         DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();
         dataSourceInitializer.setDataSource((DataSource) Objects.requireNonNull(masterDataSource().getObject()));
         dataSourceInitializer.setEnabled(true);
-        dataSourceInitializer.setDatabasePopulator(masterResourceDatabasePopulator());
+        dataSourceInitializer.setDatabasePopulator(databasePopulator);
         return dataSourceInitializer;
     }
 
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java
index 11849ef..21a5def 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java
@@ -18,38 +18,134 @@
  */
 package org.apache.syncope.core.persistence.jpa;
 
-import java.lang.reflect.InvocationTargetException;
 import java.util.HashMap;
 import java.util.Map;
 import javax.persistence.ValidationMode;
 import javax.validation.Validator;
+import org.apache.syncope.common.keymaster.client.api.ConfParamOps;
+import org.apache.syncope.common.keymaster.client.api.DomainOps;
+import org.apache.syncope.core.persistence.api.DomainHolder;
+import org.apache.syncope.core.persistence.api.DomainRegistry;
+import org.apache.syncope.core.persistence.api.dao.AccessTokenDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyMatchDAO;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.ApplicationDAO;
 import org.apache.syncope.core.persistence.api.dao.AuditConfDAO;
+import org.apache.syncope.core.persistence.api.dao.BatchDAO;
+import org.apache.syncope.core.persistence.api.dao.ConnInstanceDAO;
+import org.apache.syncope.core.persistence.api.dao.DelegationDAO;
+import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.DynRealmDAO;
+import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.ImplementationDAO;
+import org.apache.syncope.core.persistence.api.dao.MailTemplateDAO;
+import org.apache.syncope.core.persistence.api.dao.NotificationDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainAttrValueDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.dao.RelationshipTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.RemediationDAO;
+import org.apache.syncope.core.persistence.api.dao.ReportDAO;
+import org.apache.syncope.core.persistence.api.dao.ReportExecDAO;
+import org.apache.syncope.core.persistence.api.dao.ReportTemplateDAO;
+import org.apache.syncope.core.persistence.api.dao.RoleDAO;
+import org.apache.syncope.core.persistence.api.dao.SRARouteDAO;
+import org.apache.syncope.core.persistence.api.dao.SecurityQuestionDAO;
+import org.apache.syncope.core.persistence.api.dao.TaskDAO;
+import org.apache.syncope.core.persistence.api.dao.TaskExecDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.auth.AuthModuleDAO;
+import org.apache.syncope.core.persistence.api.dao.auth.AuthProfileDAO;
+import org.apache.syncope.core.persistence.api.dao.auth.CASSPDAO;
+import org.apache.syncope.core.persistence.api.dao.auth.OIDCJWKSDAO;
+import org.apache.syncope.core.persistence.api.dao.auth.OIDCRPDAO;
+import org.apache.syncope.core.persistence.api.dao.auth.SAML2IdPEntityDAO;
+import org.apache.syncope.core.persistence.api.dao.auth.SAML2SPDAO;
+import org.apache.syncope.core.persistence.api.dao.auth.SAML2SPEntityDAO;
+import org.apache.syncope.core.persistence.api.dao.auth.WAConfigDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.auth.ClientAppUtilsFactory;
+import org.apache.syncope.core.persistence.api.entity.policy.PolicyUtilsFactory;
+import org.apache.syncope.core.persistence.api.entity.task.TaskUtilsFactory;
 import org.apache.syncope.core.persistence.api.search.SearchCondVisitor;
+import org.apache.syncope.core.persistence.jpa.content.KeymasterConfParamLoader;
+import org.apache.syncope.core.persistence.jpa.content.XMLContentExporter;
+import org.apache.syncope.core.persistence.jpa.content.XMLContentLoader;
+import org.apache.syncope.core.persistence.jpa.dao.JPAAccessTokenDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPAAnyMatchDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPAAnyObjectDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPAAnySearchDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPAAnyTypeClassDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPAAnyTypeDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPAApplicationDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPAAuditConfDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPABatchDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPAConnInstanceDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPADelegationDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPADerSchemaDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPADynRealmDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPAExternalResourceDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPAGroupDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPAImplementationDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPAMailTemplateDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPANotificationDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPAPlainAttrDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPAPlainAttrValueDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPAPlainSchemaDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPAPolicyDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPARealmDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPARelationshipTypeDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPARemediationDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPAReportDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPAReportExecDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPAReportTemplateDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPARoleDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPASRARouteDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPASecurityQuestionDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPATaskDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPATaskExecDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPAUserDAO;
+import org.apache.syncope.core.persistence.jpa.dao.JPAVirSchemaDAO;
+import org.apache.syncope.core.persistence.jpa.dao.auth.JPAAuthModuleDAO;
+import org.apache.syncope.core.persistence.jpa.dao.auth.JPAAuthProfileDAO;
+import org.apache.syncope.core.persistence.jpa.dao.auth.JPACASSPDAO;
+import org.apache.syncope.core.persistence.jpa.dao.auth.JPAOIDCJWKSDAO;
+import org.apache.syncope.core.persistence.jpa.dao.auth.JPAOIDCRPDAO;
+import org.apache.syncope.core.persistence.jpa.dao.auth.JPASAML2IdPEntityDAO;
+import org.apache.syncope.core.persistence.jpa.dao.auth.JPASAML2SPDAO;
+import org.apache.syncope.core.persistence.jpa.dao.auth.JPASAML2SPEntityDAO;
+import org.apache.syncope.core.persistence.jpa.dao.auth.JPAWAConfigDAO;
+import org.apache.syncope.core.persistence.jpa.entity.JPAAnyUtilsFactory;
+import org.apache.syncope.core.persistence.jpa.entity.JPAEntityFactory;
+import org.apache.syncope.core.persistence.jpa.entity.auth.JPAClientAppUtilsFactory;
+import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPolicyUtilsFactory;
+import org.apache.syncope.core.persistence.jpa.entity.task.JPATaskUtilsFactory;
 import org.apache.syncope.core.persistence.jpa.spring.CommonEntityManagerFactoryConf;
 import org.apache.syncope.core.persistence.jpa.spring.DomainTransactionInterceptorInjector;
 import org.apache.syncope.core.persistence.jpa.spring.MultiJarAwarePersistenceUnitPostProcessor;
+import org.apache.syncope.core.spring.security.SecurityProperties;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.core.io.Resource;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.core.env.Environment;
 import org.springframework.core.io.ResourceLoader;
 import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
 
-@ComponentScan("org.apache.syncope.core.persistence.jpa")
 @EnableConfigurationProperties(PersistenceProperties.class)
 @Configuration
 public class PersistenceContext {
@@ -62,11 +158,31 @@ public class PersistenceContext {
     }
 
     @Autowired
-    private PersistenceProperties props;
+    private PersistenceProperties persistenceProperties;
+
+    @Autowired
+    private SecurityProperties securityProperties;
 
     @Autowired
     private ResourceLoader resourceLoader;
 
+    @Autowired
+    private ApplicationEventPublisher publisher;
+
+    @Autowired
+    private Environment env;
+
+    @ConditionalOnMissingBean
+    @Bean
+    public SearchCondVisitor searchCondVisitor() {
+        return new SearchCondVisitor();
+    }
+
+    @Bean
+    public Validator localValidatorFactoryBean() {
+        return new LocalValidatorFactoryBean();
+    }
+
     @ConditionalOnMissingBean
     @Bean
     public CommonEntityManagerFactoryConf commonEMFConf() {
@@ -94,94 +210,503 @@ public class PersistenceContext {
         jpaPropertyMap.put("openjpa.DataCache", "true");
         jpaPropertyMap.put("openjpa.QueryCache", "true");
 
-        jpaPropertyMap.put("openjpa.RemoteCommitProvider", props.getRemoteCommitProvider());
+        jpaPropertyMap.put("openjpa.RemoteCommitProvider", persistenceProperties.getRemoteCommitProvider());
 
         commonEMFConf.setJpaPropertyMap(jpaPropertyMap);
         return commonEMFConf;
     }
 
+    @ConditionalOnMissingBean
     @Bean
-    public EntityFactory entityFactory() throws NoSuchMethodException,
-            InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+    public XMLContentLoader xmlContentLoader() {
+        return new XMLContentLoader(
+                resourceLoader.getResource(persistenceProperties.getViewsXML()),
+                resourceLoader.getResource(persistenceProperties.getIndexesXML()),
+                env);
+    }
 
-        return props.getEntityFactory().getDeclaredConstructor().newInstance();
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public XMLContentExporter xmlContentExporter(final DomainHolder domainHolder, final RealmDAO realmDAO) {
+        return new XMLContentExporter(domainHolder, realmDAO);
     }
 
+    @ConditionalOnMissingBean
     @Bean
-    public PlainSchemaDAO plainSchemaDAO() throws NoSuchMethodException,
-            InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+    @Autowired
+    public KeymasterConfParamLoader keymasterConfParamLoader(final ConfParamOps confParamOps) {
+        return new KeymasterConfParamLoader(confParamOps);
+    }
 
-        return props.getPlainSchemaDAO().getDeclaredConstructor().newInstance();
+    @ConditionalOnMissingBean
+    @Bean
+    public DomainRegistry domainRegistry() {
+        return new DomainConfFactory(env);
     }
 
+    @ConditionalOnMissingBean
     @Bean
-    public PlainAttrDAO plainAttrDAO() throws NoSuchMethodException,
-            InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+    @Autowired
+    public RuntimeDomainLoader runtimeDomainLoader(
+            final DomainHolder domainHolder,
+            final DomainRegistry domainRegistry) {
 
-        return props.getPlainAttrDAO().getDeclaredConstructor().newInstance();
+        return new RuntimeDomainLoader(domainHolder, domainRegistry);
     }
 
+    @ConditionalOnMissingBean
     @Bean
-    public PlainAttrValueDAO plainAttrValueDAO() throws NoSuchMethodException,
-            InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+    @Autowired
+    public StartupDomainLoader startupDomainLoader(
+            final DomainOps domainOps,
+            final DomainHolder domainHolder,
+            final DomainRegistry domainRegistry) {
 
-        return props.getPlainAttrValueDAO().getDeclaredConstructor().newInstance();
+        return new StartupDomainLoader(domainOps, domainHolder, persistenceProperties, resourceLoader, domainRegistry);
     }
 
+    @ConditionalOnMissingBean
     @Bean
-    public AnySearchDAO anySearchDAO() throws NoSuchMethodException,
-            InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+    public EntityFactory entityFactory() {
+        return new JPAEntityFactory();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public AnyUtilsFactory anyUtilsFactory(
+            final @Lazy UserDAO userDAO,
+            final @Lazy GroupDAO groupDAO,
+            final @Lazy AnyObjectDAO anyObjectDAO,
+            final @Lazy EntityFactory entityFactory) {
 
-        return props.getAnySearchDAO().getDeclaredConstructor().newInstance();
+        return new JPAAnyUtilsFactory(userDAO, groupDAO, anyObjectDAO, entityFactory);
     }
 
+    @ConditionalOnMissingBean
     @Bean
-    public SearchCondVisitor searchCondVisitor() throws NoSuchMethodException,
-            InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+    public ClientAppUtilsFactory clientAppUtilsFactory() {
+        return new JPAClientAppUtilsFactory();
+    }
 
-        return props.getSearchCondVisitor().getDeclaredConstructor().newInstance();
+    @ConditionalOnMissingBean
+    @Bean
+    public PolicyUtilsFactory policyUtilsFactory() {
+        return new JPAPolicyUtilsFactory();
     }
 
+    @ConditionalOnMissingBean
     @Bean
-    public UserDAO userDAO() throws NoSuchMethodException,
-            InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+    @Autowired
+    public TaskUtilsFactory taskUtilsFactory(final @Lazy EntityFactory entityFactory) {
+        return new JPATaskUtilsFactory(entityFactory);
+    }
 
-        return props.getUserDAO().getDeclaredConstructor().newInstance();
+    @ConditionalOnMissingBean
+    @Bean
+    public AccessTokenDAO accessTokenDAO() {
+        return new JPAAccessTokenDAO();
     }
 
+    @ConditionalOnMissingBean
     @Bean
-    public GroupDAO groupDAO() throws NoSuchMethodException,
-            InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+    @Autowired
+    public ApplicationDAO applicationDAO(final RoleDAO roleDAO, final @Lazy UserDAO userDAO) {
+        return new JPAApplicationDAO(roleDAO, userDAO);
+    }
 
-        return props.getGroupDAO().getDeclaredConstructor().newInstance();
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public AnyMatchDAO anyMatchDAO(
+            final @Lazy UserDAO userDAO,
+            final @Lazy GroupDAO groupDAO,
+            final @Lazy AnyObjectDAO anyObjectDAO,
+            final RealmDAO realmDAO,
+            final PlainSchemaDAO plainSchemaDAO,
+            final AnyUtilsFactory anyUtilsFactory) {
+
+        return new JPAAnyMatchDAO(userDAO, groupDAO, anyObjectDAO, realmDAO, plainSchemaDAO, anyUtilsFactory);
     }
 
+    @ConditionalOnMissingBean
     @Bean
-    public AnyObjectDAO anyObjectDAO() throws NoSuchMethodException,
-            InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+    @Autowired
+    public AnyObjectDAO anyObjectDAO(
+            final AnyUtilsFactory anyUtilsFactory,
+            final @Lazy PlainSchemaDAO plainSchemaDAO,
+            final @Lazy DerSchemaDAO derSchemaDAO,
+            final @Lazy DynRealmDAO dynRealmDAO,
+            final @Lazy UserDAO userDAO,
+            final @Lazy GroupDAO groupDAO) {
+
+        return new JPAAnyObjectDAO(
+                anyUtilsFactory,
+                publisher,
+                plainSchemaDAO,
+                derSchemaDAO,
+                dynRealmDAO,
+                userDAO,
+                groupDAO);
+    }
 
-        return props.getAnyObjectDAO().getDeclaredConstructor().newInstance();
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public AnySearchDAO anySearchDAO(
+            final RealmDAO realmDAO,
+            final @Lazy DynRealmDAO dynRealmDAO,
+            final @Lazy UserDAO userDAO,
+            final @Lazy GroupDAO groupDAO,
+            final @Lazy AnyObjectDAO anyObjectDAO,
+            final PlainSchemaDAO schemaDAO,
+            final EntityFactory entityFactory,
+            final AnyUtilsFactory anyUtilsFactory) {
+
+        return new JPAAnySearchDAO(
+                realmDAO,
+                dynRealmDAO,
+                userDAO,
+                groupDAO,
+                anyObjectDAO,
+                schemaDAO,
+                entityFactory,
+                anyUtilsFactory);
     }
 
+    @ConditionalOnMissingBean
     @Bean
-    public AuditConfDAO auditConfDAO() throws NoSuchMethodException,
-            InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+    @Autowired
+    public AnyTypeDAO anyTypeDAO(final RemediationDAO remediationDAO) {
+        return new JPAAnyTypeDAO(remediationDAO);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public AnyTypeClassDAO anyTypeClassDAO(
+            final AnyTypeDAO anyTypeDAO,
+            final PlainSchemaDAO plainSchemaDAO,
+            final DerSchemaDAO derSchemaDAO,
+            final VirSchemaDAO virSchemaDAO,
+            final @Lazy GroupDAO groupDAO,
+            final ExternalResourceDAO resourceDAO) {
+
+        return new JPAAnyTypeClassDAO(anyTypeDAO, plainSchemaDAO, derSchemaDAO, virSchemaDAO, groupDAO, resourceDAO);
+    }
 
-        return props.getAuditConfDAO().getDeclaredConstructor().newInstance();
+    @ConditionalOnMissingBean
+    @Bean
+    public AuditConfDAO auditConfDAO() {
+        return new JPAAuditConfDAO();
     }
 
+    @ConditionalOnMissingBean
     @Bean
-    public Validator localValidatorFactoryBean() {
-        return new LocalValidatorFactoryBean();
+    public AuthModuleDAO authModuleDAO() {
+        return new JPAAuthModuleDAO();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public AuthProfileDAO authProfileDAO() {
+        return new JPAAuthProfileDAO();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public BatchDAO batchDAO() {
+        return new JPABatchDAO();
     }
 
+    @ConditionalOnMissingBean
     @Bean
-    public Resource viewsXML() {
-        return resourceLoader.getResource(props.getViewsXML());
+    public CASSPDAO casSPDAO() {
+        return new JPACASSPDAO();
     }
 
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public ConnInstanceDAO connInstanceDAO(final @Lazy ExternalResourceDAO resourceDAO) {
+        return new JPAConnInstanceDAO(resourceDAO);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public DelegationDAO delegationDAO() {
+        return new JPADelegationDAO();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public DerSchemaDAO derSchemaDAO(final @Lazy ExternalResourceDAO resourceDAO) {
+        return new JPADerSchemaDAO(resourceDAO);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public DynRealmDAO dynRealmDAO(
+            final @Lazy UserDAO userDAO,
+            final @Lazy GroupDAO groupDAO,
+            final @Lazy AnyObjectDAO anyObjectDAO,
+            final AnySearchDAO searchDAO,
+            final AnyMatchDAO anyMatchDAO,
+            final SearchCondVisitor searchCondVisitor) {
+
+        return new JPADynRealmDAO(
+                publisher,
+                userDAO,
+                groupDAO,
+                anyObjectDAO,
+                searchDAO,
+                anyMatchDAO,
+                searchCondVisitor);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public GroupDAO groupDAO(
+            final AnyUtilsFactory anyUtilsFactory,
+            final @Lazy PlainSchemaDAO plainSchemaDAO,
+            final @Lazy DerSchemaDAO derSchemaDAO,
+            final @Lazy DynRealmDAO dynRealmDAO,
+            final AnyMatchDAO anyMatchDAO,
+            final PlainAttrDAO plainAttrDAO,
+            final @Lazy UserDAO userDAO,
+            final @Lazy AnyObjectDAO anyObjectDAO,
+            final AnySearchDAO anySearchDAO,
+            final SearchCondVisitor searchCondVisitor) {
+
+        return new JPAGroupDAO(
+                anyUtilsFactory,
+                publisher,
+                plainSchemaDAO,
+                derSchemaDAO,
+                dynRealmDAO,
+                anyMatchDAO,
+                plainAttrDAO,
+                userDAO,
+                anyObjectDAO,
+                anySearchDAO,
+                searchCondVisitor);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public ImplementationDAO implementationDAO() {
+        return new JPAImplementationDAO();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public MailTemplateDAO mailTemplateDAO() {
+        return new JPAMailTemplateDAO();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public NotificationDAO notificationDAO(final TaskDAO taskDAO) {
+        return new JPANotificationDAO(taskDAO);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public OIDCJWKSDAO oidcJWKSDAO() {
+        return new JPAOIDCJWKSDAO();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public OIDCRPDAO oidcRPDAO() {
+        return new JPAOIDCRPDAO();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public PlainAttrDAO plainAttrDAO() {
+        return new JPAPlainAttrDAO();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public PlainAttrValueDAO plainAttrValueDAO() {
+        return new JPAPlainAttrValueDAO();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public PlainSchemaDAO plainSchemaDAO(
+            final AnyUtilsFactory anyUtilsFactory,
+            final PlainAttrDAO plainAttrDAO,
+            final @Lazy ExternalResourceDAO resourceDAO) {
+
+        return new JPAPlainSchemaDAO(anyUtilsFactory, plainAttrDAO, resourceDAO);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public PolicyDAO policyDAO(
+            final @Lazy RealmDAO realmDAO,
+            final @Lazy ExternalResourceDAO resourceDAO) {
+
+        return new JPAPolicyDAO(realmDAO, resourceDAO);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public RealmDAO realmDAO(final @Lazy RoleDAO roleDAO) {
+        return new JPARealmDAO(roleDAO);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public RelationshipTypeDAO relationshipTypeDAO() {
+        return new JPARelationshipTypeDAO();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public RemediationDAO remediationDAO() {
+        return new JPARemediationDAO();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public ReportTemplateDAO reportTemplateDAO() {
+        return new JPAReportTemplateDAO();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public ReportDAO reportDAO() {
+        return new JPAReportDAO();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public ReportExecDAO reportExecDAO() {
+        return new JPAReportExecDAO();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public ExternalResourceDAO resourceDAO(
+            final TaskDAO taskDAO,
+            final AnyObjectDAO anyObjectDAO,
+            final UserDAO userDAO,
+            final GroupDAO groupDAO,
+            final PolicyDAO policyDAO,
+            final VirSchemaDAO virSchemaDAO,
+            final RealmDAO realmDAO) {
+
+        return new JPAExternalResourceDAO(taskDAO, anyObjectDAO, userDAO, groupDAO, policyDAO, virSchemaDAO, realmDAO);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public RoleDAO roleDAO(
+            final @Lazy AnyMatchDAO anyMatchDAO,
+            final @Lazy AnySearchDAO anySearchDAO,
+            final DelegationDAO delegationDAO,
+            final SearchCondVisitor searchCondVisitor) {
+
+        return new JPARoleDAO(anyMatchDAO, publisher, anySearchDAO, delegationDAO, searchCondVisitor);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public SAML2SPDAO saml2SPDAO() {
+        return new JPASAML2SPDAO();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public SAML2IdPEntityDAO saml2IdPEntityDAO() {
+        return new JPASAML2IdPEntityDAO();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public SAML2SPEntityDAO saml2SPEntityDAO() {
+        return new JPASAML2SPEntityDAO();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public SecurityQuestionDAO securityQuestionDAO(final UserDAO userDAO) {
+        return new JPASecurityQuestionDAO(userDAO);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    public SRARouteDAO sraRouteDAO() {
+        return new JPASRARouteDAO();
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public TaskDAO taskDAO(final RemediationDAO remediationDAO) {
+        return new JPATaskDAO(remediationDAO);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public TaskExecDAO taskExecDAO(final TaskDAO taskDAO) {
+        return new JPATaskExecDAO(taskDAO);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public UserDAO userDAO(
+            final AnyUtilsFactory anyUtilsFactory,
+            final @Lazy PlainSchemaDAO plainSchemaDAO,
+            final @Lazy DerSchemaDAO derSchemaDAO,
+            final @Lazy DynRealmDAO dynRealmDAO,
+            final RoleDAO roleDAO,
+            final AccessTokenDAO accessTokenDAO,
+            final RealmDAO realmDAO,
+            final @Lazy GroupDAO groupDAO,
+            final DelegationDAO delegationDAO) {
+
+        return new JPAUserDAO(
+                anyUtilsFactory,
+                publisher,
+                plainSchemaDAO,
+                derSchemaDAO,
+                dynRealmDAO,
+                roleDAO,
+                accessTokenDAO,
+                realmDAO,
+                groupDAO,
+                delegationDAO,
+                securityProperties);
+    }
+
+    @ConditionalOnMissingBean
+    @Bean
+    @Autowired
+    public VirSchemaDAO virSchemaDAO(final @Lazy ExternalResourceDAO resourceDAO) {
+        return new JPAVirSchemaDAO(resourceDAO);
+    }
+
+    @ConditionalOnMissingBean
     @Bean
-    public Resource indexesXML() {
-        return resourceLoader.getResource(props.getIndexesXML());
+    public WAConfigDAO waConfigDAO() {
+        return new JPAWAConfigDAO();
     }
 }
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceProperties.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceProperties.java
index 4af0eea..03fd3c4 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceProperties.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceProperties.java
@@ -20,25 +20,6 @@ package org.apache.syncope.core.persistence.jpa;
 
 import java.util.ArrayList;
 import java.util.List;
-import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
-import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
-import org.apache.syncope.core.persistence.api.dao.AuditConfDAO;
-import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO;
-import org.apache.syncope.core.persistence.api.dao.PlainAttrValueDAO;
-import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.EntityFactory;
-import org.apache.syncope.core.persistence.api.search.SearchCondVisitor;
-import org.apache.syncope.core.persistence.jpa.dao.JPAAnyObjectDAO;
-import org.apache.syncope.core.persistence.jpa.dao.JPAAnySearchDAO;
-import org.apache.syncope.core.persistence.jpa.dao.JPAAuditConfDAO;
-import org.apache.syncope.core.persistence.jpa.dao.JPAGroupDAO;
-import org.apache.syncope.core.persistence.jpa.dao.JPAPlainAttrDAO;
-import org.apache.syncope.core.persistence.jpa.dao.JPAPlainAttrValueDAO;
-import org.apache.syncope.core.persistence.jpa.dao.JPAPlainSchemaDAO;
-import org.apache.syncope.core.persistence.jpa.dao.JPAUserDAO;
-import org.apache.syncope.core.persistence.jpa.entity.JPAEntityFactory;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.boot.context.properties.NestedConfigurationProperty;
 
@@ -49,26 +30,6 @@ public class PersistenceProperties {
 
     private String metaDataFactory;
 
-    private Class<? extends EntityFactory> entityFactory = JPAEntityFactory.class;
-
-    private Class<? extends PlainSchemaDAO> plainSchemaDAO = JPAPlainSchemaDAO.class;
-
-    private Class<? extends PlainAttrDAO> plainAttrDAO = JPAPlainAttrDAO.class;
-
-    private Class<? extends PlainAttrValueDAO> plainAttrValueDAO = JPAPlainAttrValueDAO.class;
-
-    private Class<? extends AnySearchDAO> anySearchDAO = JPAAnySearchDAO.class;
-
-    private Class<? extends SearchCondVisitor> searchCondVisitor = SearchCondVisitor.class;
-
-    private Class<? extends UserDAO> userDAO = JPAUserDAO.class;
-
-    private Class<? extends GroupDAO> groupDAO = JPAGroupDAO.class;
-
-    private Class<? extends AnyObjectDAO> anyObjectDAO = JPAAnyObjectDAO.class;
-
-    private Class<? extends AuditConfDAO> auditConfDAO = JPAAuditConfDAO.class;
-
     private String viewsXML = "classpath:views.xml";
 
     private String indexesXML = "classpath:indexes.xml";
@@ -92,86 +53,6 @@ public class PersistenceProperties {
         this.metaDataFactory = metaDataFactory;
     }
 
-    public Class<? extends EntityFactory> getEntityFactory() {
-        return entityFactory;
-    }
-
-    public void setEntityFactory(final Class<? extends EntityFactory> entityFactory) {
-        this.entityFactory = entityFactory;
-    }
-
-    public Class<? extends PlainSchemaDAO> getPlainSchemaDAO() {
-        return plainSchemaDAO;
-    }
-
-    public void setPlainSchemaDAO(final Class<? extends PlainSchemaDAO> plainSchemaDAO) {
-        this.plainSchemaDAO = plainSchemaDAO;
-    }
-
-    public Class<? extends PlainAttrDAO> getPlainAttrDAO() {
-        return plainAttrDAO;
-    }
-
-    public void setPlainAttrDAO(final Class<? extends PlainAttrDAO> plainAttrDAO) {
-        this.plainAttrDAO = plainAttrDAO;
-    }
-
-    public Class<? extends PlainAttrValueDAO> getPlainAttrValueDAO() {
-        return plainAttrValueDAO;
-    }
-
-    public void setPlainAttrValueDAO(final Class<? extends PlainAttrValueDAO> plainAttrValueDAO) {
-        this.plainAttrValueDAO = plainAttrValueDAO;
-    }
-
-    public Class<? extends AnySearchDAO> getAnySearchDAO() {
-        return anySearchDAO;
-    }
-
-    public void setAnySearchDAO(final Class<? extends AnySearchDAO> anySearchDAO) {
-        this.anySearchDAO = anySearchDAO;
-    }
-
-    public Class<? extends SearchCondVisitor> getSearchCondVisitor() {
-        return searchCondVisitor;
-    }
-
-    public void setSearchCondVisitor(final Class<? extends SearchCondVisitor> searchCondVisitor) {
-        this.searchCondVisitor = searchCondVisitor;
-    }
-
-    public Class<? extends UserDAO> getUserDAO() {
-        return userDAO;
-    }
-
-    public void setUserDAO(final Class<? extends UserDAO> userDAO) {
-        this.userDAO = userDAO;
-    }
-
-    public Class<? extends GroupDAO> getGroupDAO() {
-        return groupDAO;
-    }
-
-    public void setGroupDAO(final Class<? extends GroupDAO> groupDAO) {
-        this.groupDAO = groupDAO;
-    }
-
-    public Class<? extends AnyObjectDAO> getAnyObjectDAO() {
-        return anyObjectDAO;
-    }
-
-    public void setAnyObjectDAO(final Class<? extends AnyObjectDAO> anyObjectDAO) {
-        this.anyObjectDAO = anyObjectDAO;
-    }
-
-    public Class<? extends AuditConfDAO> getAuditConfDAO() {
-        return auditConfDAO;
-    }
-
-    public void setAuditConfDAO(final Class<? extends AuditConfDAO> auditConfDAO) {
-        this.auditConfDAO = auditConfDAO;
-    }
-
     public String getViewsXML() {
         return viewsXML;
     }
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/RuntimeDomainLoader.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/RuntimeDomainLoader.java
index 9bfc909..1269a87 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/RuntimeDomainLoader.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/RuntimeDomainLoader.java
@@ -23,24 +23,24 @@ import org.apache.syncope.common.keymaster.client.api.DomainWatcher;
 import org.apache.syncope.common.keymaster.client.api.model.Domain;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
 import org.apache.syncope.core.persistence.api.DomainHolder;
 import org.apache.syncope.core.persistence.api.DomainRegistry;
 import org.apache.syncope.core.persistence.api.SyncopeCoreLoader;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.springframework.aop.support.AopUtils;
 
-@Component
 public class RuntimeDomainLoader implements DomainWatcher {
 
-    private static final Logger LOG = LoggerFactory.getLogger(RuntimeDomainLoader.class);
+    protected static final Logger LOG = LoggerFactory.getLogger(RuntimeDomainLoader.class);
 
-    @Autowired
-    private DomainHolder domainHolder;
+    protected final DomainHolder domainHolder;
 
-    @Autowired
-    private DomainRegistry domainRegistry;
+    protected final DomainRegistry domainRegistry;
+
+    public RuntimeDomainLoader(final DomainHolder domainHolder, final DomainRegistry domainRegistry) {
+        this.domainHolder = domainHolder;
+        this.domainRegistry = domainRegistry;
+    }
 
     @Override
     public void added(final Domain domain) {
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/StartupDomainLoader.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/StartupDomainLoader.java
index b3a6d3e..0dcdeb7 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/StartupDomainLoader.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/StartupDomainLoader.java
@@ -30,30 +30,36 @@ import org.apache.syncope.core.persistence.api.DomainRegistry;
 import org.apache.syncope.core.persistence.api.SyncopeCoreLoader;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.Ordered;
 import org.springframework.core.io.ResourceLoader;
-import org.springframework.stereotype.Component;
 
-@Component
 public class StartupDomainLoader implements SyncopeCoreLoader {
 
-    private static final Logger LOG = LoggerFactory.getLogger(StartupDomainLoader.class);
+    protected static final Logger LOG = LoggerFactory.getLogger(StartupDomainLoader.class);
 
-    @Autowired
-    private DomainOps domainOps;
+    protected final DomainOps domainOps;
 
-    @Autowired
-    private DomainHolder domainHolder;
+    protected final DomainHolder domainHolder;
 
-    @Autowired
-    private PersistenceProperties persistenceProperties;
+    protected final PersistenceProperties persistenceProperties;
 
-    @Autowired
-    private ResourceLoader resourceLoader;
+    protected final ResourceLoader resourceLoader;
 
-    @Autowired
-    private DomainRegistry domainRegistry;
+    protected final DomainRegistry domainRegistry;
+
+    public StartupDomainLoader(
+            final DomainOps domainOps,
+            final DomainHolder domainHolder,
+            final PersistenceProperties persistenceProperties,
+            final ResourceLoader resourceLoader,
+            final DomainRegistry domainRegistry) {
+
+        this.domainOps = domainOps;
+        this.domainHolder = domainHolder;
+        this.persistenceProperties = persistenceProperties;
+        this.resourceLoader = resourceLoader;
+        this.domainRegistry = domainRegistry;
+    }
 
     @Override
     public int getOrder() {
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/KeymasterConfParamLoader.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/KeymasterConfParamLoader.java
index fcda05b..0c6e1a7 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/KeymasterConfParamLoader.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/KeymasterConfParamLoader.java
@@ -30,21 +30,21 @@ import org.apache.syncope.core.persistence.api.content.ConfParamLoader;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
 
 /**
  * Initialize Keymaster with default content if no data is present already.
  */
-@Component
 public class KeymasterConfParamLoader implements ConfParamLoader {
 
-    private static final Logger LOG = LoggerFactory.getLogger(KeymasterConfParamLoader.class);
+    protected static final Logger LOG = LoggerFactory.getLogger(KeymasterConfParamLoader.class);
 
-    private static final ObjectMapper MAPPER = new ObjectMapper();
+    protected static final ObjectMapper MAPPER = new ObjectMapper();
 
-    @Autowired
-    private ConfParamOps confParamOps;
+    protected final ConfParamOps confParamOps;
+
+    public KeymasterConfParamLoader(final ConfParamOps confParamOps) {
+        this.confParamOps = confParamOps;
+    }
 
     @Override
     public int getOrder() {
@@ -76,7 +76,7 @@ public class KeymasterConfParamLoader implements ConfParamLoader {
         }
     }
 
-    private void loadDefaultContent(final String domain, final InputStream contentJSON)
+    protected void loadDefaultContent(final String domain, final InputStream contentJSON)
             throws IOException {
 
         try (contentJSON) {
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
index d71be3e..397bc9b 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
@@ -93,22 +93,19 @@ import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.jdbc.datasource.DataSourceUtils;
 import org.springframework.orm.jpa.EntityManagerFactoryUtils;
-import org.springframework.stereotype.Component;
 import org.xml.sax.SAXException;
 import org.xml.sax.helpers.AttributesImpl;
 
 /**
  * Export internal storage content as XML.
  */
-@Component
 public class XMLContentExporter implements ContentExporter {
 
-    private static final Logger LOG = LoggerFactory.getLogger(XMLContentExporter.class);
+    protected static final Logger LOG = LoggerFactory.getLogger(XMLContentExporter.class);
 
-    private static final Set<String> TABLE_PREFIXES_TO_BE_EXCLUDED = Stream.of(
+    protected static final Set<String> TABLE_PREFIXES_TO_BE_EXCLUDED = Stream.of(
             "QRTZ_", "LOGGING", "NotificationTask_recipients", AuditConfDAO.AUDIT_ENTRY_TABLE, JPAReportExec.TABLE,
             JPATaskExec.TABLE, JPAUser.TABLE, JPAUPlainAttr.TABLE, JPAUPlainAttrValue.TABLE,
             JPAUPlainAttrUniqueValue.TABLE, JPAURelationship.TABLE, JPAUMembership.TABLE,
@@ -116,24 +113,18 @@ public class XMLContentExporter implements ContentExporter {
             JPAARelationship.TABLE, JPAAMembership.TABLE, JPAAccessToken.TABLE
     ).collect(Collectors.toCollection(HashSet::new));
 
-    private static final Map<String, String> TABLES_TO_BE_FILTERED =
+    protected static final Map<String, String> TABLES_TO_BE_FILTERED =
             Map.of("TASK", "DTYPE <> 'PropagationTask' AND DTYPE <> 'NotificationTask'");
 
-    private static final Map<String, Set<String>> COLUMNS_TO_BE_NULLIFIED =
+    protected static final Map<String, Set<String>> COLUMNS_TO_BE_NULLIFIED =
             Map.of("SYNCOPEGROUP", Set.of("USEROWNER_ID"));
 
-    @Autowired
-    private DomainHolder domainHolder;
-
-    @Autowired
-    private RealmDAO realmDAO;
-
-    private static boolean isTableAllowed(final String tableName) {
+    protected static boolean isTableAllowed(final String tableName) {
         return TABLE_PREFIXES_TO_BE_EXCLUDED.stream().
                 allMatch(prefix -> !tableName.toUpperCase().startsWith(prefix.toUpperCase()));
     }
 
-    private static List<String> sortByForeignKeys(final String dbSchema, final Connection conn,
+    protected static List<String> sortByForeignKeys(final String dbSchema, final Connection conn,
             final Set<String> tableNames)
             throws SQLException {
 
@@ -204,7 +195,7 @@ public class XMLContentExporter implements ContentExporter {
         return sortedTableNames;
     }
 
-    private static String getValues(final ResultSet rs, final String columnName, final Integer columnType)
+    protected static String getValues(final ResultSet rs, final String columnName, final Integer columnType)
             throws SQLException {
 
         String res = null;
@@ -251,7 +242,16 @@ public class XMLContentExporter implements ContentExporter {
         return res;
     }
 
-    private String columnName(final Supplier<Stream<Attribute<?, ?>>> attrs, final String columnName) {
+    protected final DomainHolder domainHolder;
+
+    protected final RealmDAO realmDAO;
+
+    public XMLContentExporter(final DomainHolder domainHolder, final RealmDAO realmDAO) {
+        this.domainHolder = domainHolder;
+        this.realmDAO = realmDAO;
+    }
+
+    protected String columnName(final Supplier<Stream<Attribute<?, ?>>> attrs, final String columnName) {
         String name = attrs.get().map(attr -> {
             if (attr.getName().equalsIgnoreCase(columnName)) {
                 return attr.getName();
@@ -276,12 +276,12 @@ public class XMLContentExporter implements ContentExporter {
         return name;
     }
 
-    private boolean isTask(final String tableName) {
+    protected boolean isTask(final String tableName) {
         return "TASK".equalsIgnoreCase(tableName);
     }
 
     @SuppressWarnings("unchecked")
-    private void exportTable(
+    protected void exportTable(
             final TransformerHandler handler,
             final Connection conn,
             final String tableName,
@@ -427,11 +427,11 @@ public class XMLContentExporter implements ContentExporter {
         }
     }
 
-    private Set<EntityType<?>> taskEntities(final Set<EntityType<?>> entityTypes) {
+    protected Set<EntityType<?>> taskEntities(final Set<EntityType<?>> entityTypes) {
         return entityTypes.stream().filter(e -> e.getName().endsWith("Task")).collect(Collectors.toSet());
     }
 
-    private BidiMap<String, EntityType<?>> entities(final Set<EntityType<?>> entityTypes) {
+    protected BidiMap<String, EntityType<?>> entities(final Set<EntityType<?>> entityTypes) {
         BidiMap<String, EntityType<?>> entities = new DualHashBidiMap<>();
         entityTypes.forEach(entity -> {
             Table table = entity.getBindableJavaType().getAnnotation(Table.class);
@@ -443,7 +443,7 @@ public class XMLContentExporter implements ContentExporter {
         return entities;
     }
 
-    private Map<String, Pair<String, String>> relationTables(final BidiMap<String, EntityType<?>> entities) {
+    protected Map<String, Pair<String, String>> relationTables(final BidiMap<String, EntityType<?>> entities) {
         Map<String, Pair<String, String>> relationTables = new HashMap<>();
         entities.values().stream().forEach(e -> e.getAttributes().stream().
                 filter(a -> a.getPersistentAttributeType() != Attribute.PersistentAttributeType.BASIC).
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java
index 8347ef6..eda1a1a 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java
@@ -31,32 +31,36 @@ import org.apache.syncope.core.persistence.jpa.entity.JPARealm;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.env.Environment;
 import org.springframework.core.io.Resource;
 import org.springframework.core.io.support.PropertiesLoaderUtils;
 import org.springframework.dao.DataAccessException;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.orm.jpa.EntityManagerFactoryUtils;
-import org.springframework.stereotype.Component;
 import org.xml.sax.SAXException;
 
 /**
  * Initialize Database with default content if no data is present already.
  */
-@Component
 public class XMLContentLoader implements ContentLoader {
 
-    private static final Logger LOG = LoggerFactory.getLogger(XMLContentLoader.class);
+    protected static final Logger LOG = LoggerFactory.getLogger(XMLContentLoader.class);
 
-    @javax.annotation.Resource(name = "viewsXML")
-    private Resource viewsXML;
+    protected final Resource viewsXML;
 
-    @javax.annotation.Resource(name = "indexesXML")
-    private Resource indexesXML;
+    protected final Resource indexesXML;
 
-    @Autowired
-    private Environment env;
+    protected final Environment env;
+
+    public XMLContentLoader(
+            final Resource viewsXML,
+            final Resource indexesXML,
+            final Environment env) {
+
+        this.viewsXML = viewsXML;
+        this.indexesXML = indexesXML;
+        this.env = env;
+    }
 
     @Override
     public int getOrder() {
@@ -105,7 +109,7 @@ public class XMLContentLoader implements ContentLoader {
         }
     }
 
-    private void loadDefaultContent(
+    protected void loadDefaultContent(
             final String domain, final InputStream contentXML, final DataSource dataSource)
             throws IOException, ParserConfigurationException, SAXException {
 
@@ -119,7 +123,7 @@ public class XMLContentLoader implements ContentLoader {
         }
     }
 
-    private void createViews(final String domain, final DataSource dataSource) throws IOException {
+    protected void createViews(final String domain, final DataSource dataSource) throws IOException {
         LOG.debug("[{}] Creating views", domain);
 
         JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
@@ -137,7 +141,7 @@ public class XMLContentLoader implements ContentLoader {
         LOG.debug("Views created");
     }
 
-    private void createIndexes(final String domain, final DataSource dataSource) throws IOException {
+    protected void createIndexes(final String domain, final DataSource dataSource) throws IOException {
         LOG.debug("[{}] Creating indexes", domain);
 
         JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
index 74ba5c1..8ac8d40 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
@@ -61,34 +61,38 @@ import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationEventPublisher;
-import org.springframework.context.annotation.Lazy;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
 public abstract class AbstractAnyDAO<A extends Any<?>> extends AbstractDAO<A> implements AnyDAO<A> {
 
-    @Autowired
-    protected AnyUtilsFactory anyUtilsFactory;
+    protected final AnyUtilsFactory anyUtilsFactory;
 
-    @Autowired
-    protected ApplicationEventPublisher publisher;
+    protected final ApplicationEventPublisher publisher;
 
-    @Autowired
-    @Lazy
-    protected PlainSchemaDAO plainSchemaDAO;
+    protected final PlainSchemaDAO plainSchemaDAO;
 
-    @Autowired
-    @Lazy
-    protected DerSchemaDAO derSchemaDAO;
+    protected final DerSchemaDAO derSchemaDAO;
 
-    @Autowired
-    @Lazy
-    protected DynRealmDAO dynRealmDAO;
+    protected final DynRealmDAO dynRealmDAO;
 
     private AnyUtils anyUtils;
 
+    public AbstractAnyDAO(
+            final AnyUtilsFactory anyUtilsFactory,
+            final ApplicationEventPublisher publisher,
+            final PlainSchemaDAO plainSchemaDAO,
+            final DerSchemaDAO derSchemaDAO,
+            final DynRealmDAO dynRealmDAO) {
+
+        this.anyUtilsFactory = anyUtilsFactory;
+        this.publisher = publisher;
+        this.plainSchemaDAO = plainSchemaDAO;
+        this.derSchemaDAO = derSchemaDAO;
+        this.dynRealmDAO = dynRealmDAO;
+    }
+
     protected abstract AnyUtils init();
 
     protected AnyUtils anyUtils() {
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnySearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnySearchDAO.java
index 141edb1..38b5d55 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnySearchDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnySearchDAO.java
@@ -62,7 +62,6 @@ import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.jpa.entity.JPAPlainSchema;
-import org.springframework.beans.factory.annotation.Autowired;
 
 public abstract class AbstractAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO {
 
@@ -72,30 +71,6 @@ public abstract class AbstractAnySearchDAO extends AbstractDAO<Any<?>> implement
 
     protected static final String[] RELATIONSHIP_FIELDS = new String[] { "realm", "userOwner", "groupOwner" };
 
-    @Autowired
-    protected RealmDAO realmDAO;
-
-    @Autowired
-    protected DynRealmDAO dynRealmDAO;
-
-    @Autowired
-    protected AnyObjectDAO anyObjectDAO;
-
-    @Autowired
-    protected UserDAO userDAO;
-
-    @Autowired
-    protected GroupDAO groupDAO;
-
-    @Autowired
-    protected PlainSchemaDAO schemaDAO;
-
-    @Autowired
-    protected EntityFactory entityFactory;
-
-    @Autowired
-    protected AnyUtilsFactory anyUtilsFactory;
-
     protected static SearchCond buildEffectiveCond(
             final SearchCond cond,
             final Set<String> dynRealmKeys,
@@ -135,6 +110,42 @@ public abstract class AbstractAnySearchDAO extends AbstractDAO<Any<?>> implement
         return SearchCond.getAnd(result);
     }
 
+    protected final RealmDAO realmDAO;
+
+    protected final DynRealmDAO dynRealmDAO;
+
+    protected final UserDAO userDAO;
+
+    protected final GroupDAO groupDAO;
+
+    protected final AnyObjectDAO anyObjectDAO;
+
+    protected final PlainSchemaDAO plainSchemaDAO;
+
+    protected final EntityFactory entityFactory;
+
+    protected final AnyUtilsFactory anyUtilsFactory;
+
+    public AbstractAnySearchDAO(
+            final RealmDAO realmDAO,
+            final DynRealmDAO dynRealmDAO,
+            final UserDAO userDAO,
+            final GroupDAO groupDAO,
+            final AnyObjectDAO anyObjectDAO,
+            final PlainSchemaDAO plainSchemaDAO,
+            final EntityFactory entityFactory,
+            final AnyUtilsFactory anyUtilsFactory) {
+
+        this.realmDAO = realmDAO;
+        this.dynRealmDAO = dynRealmDAO;
+        this.userDAO = userDAO;
+        this.groupDAO = groupDAO;
+        this.anyObjectDAO = anyObjectDAO;
+        this.plainSchemaDAO = plainSchemaDAO;
+        this.entityFactory = entityFactory;
+        this.anyUtilsFactory = anyUtilsFactory;
+    }
+
     protected abstract int doCount(Set<String> adminRealms, SearchCond cond, AnyTypeKind kind);
 
     @Override
@@ -176,7 +187,7 @@ public abstract class AbstractAnySearchDAO extends AbstractDAO<Any<?>> implement
     protected Pair<PlainSchema, PlainAttrValue> check(final AttrCond cond, final AnyTypeKind kind) {
         AnyUtils anyUtils = anyUtilsFactory.getInstance(kind);
 
-        PlainSchema schema = schemaDAO.find(cond.getSchema());
+        PlainSchema schema = plainSchemaDAO.find(cond.getSchema());
         if (schema == null) {
             LOG.warn("Ignoring invalid schema '{}'", cond.getSchema());
             throw new IllegalArgumentException();
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
index 899c3a5..4ad4d9c 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
@@ -25,10 +25,8 @@ import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Configurable;
 import org.springframework.orm.jpa.EntityManagerFactoryUtils;
 
-@Configurable
 public abstract class AbstractDAO<E extends Entity> implements DAO<E> {
 
     protected static final Logger LOG = LoggerFactory.getLogger(DAO.class);
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAccessTokenDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAccessTokenDAO.java
index f582cc9..3753b74 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAccessTokenDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAccessTokenDAO.java
@@ -28,11 +28,9 @@ import org.apache.syncope.core.persistence.api.dao.AccessTokenDAO;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.entity.AccessToken;
 import org.apache.syncope.core.persistence.jpa.entity.JPAAccessToken;
-import org.springframework.stereotype.Repository;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.ReflectionUtils;
 
-@Repository
 public class JPAAccessTokenDAO extends AbstractDAO<AccessToken> implements AccessTokenDAO {
 
     @Transactional(readOnly = true)
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyMatchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyMatchDAO.java
index d6c398a..7419751 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyMatchDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyMatchDAO.java
@@ -59,8 +59,6 @@ import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 import org.apache.syncope.core.persistence.api.dao.AnyMatchDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
@@ -69,26 +67,35 @@ import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.jpa.entity.JPAPlainSchema;
 import org.springframework.beans.BeanUtils;
 
-@Component
 public class JPAAnyMatchDAO extends AbstractDAO<Any<?>> implements AnyMatchDAO {
 
-    @Autowired
-    private UserDAO userDAO;
+    protected final UserDAO userDAO;
 
-    @Autowired
-    private GroupDAO groupDAO;
+    protected final GroupDAO groupDAO;
 
-    @Autowired
-    private AnyObjectDAO anyObjectDAO;
+    protected final AnyObjectDAO anyObjectDAO;
 
-    @Autowired
-    private RealmDAO realmDAO;
+    protected final RealmDAO realmDAO;
 
-    @Autowired
-    private PlainSchemaDAO plainSchemaDAO;
+    protected final PlainSchemaDAO plainSchemaDAO;
 
-    @Autowired
-    private AnyUtilsFactory anyUtilsFactory;
+    protected final AnyUtilsFactory anyUtilsFactory;
+
+    public JPAAnyMatchDAO(
+            final UserDAO userDAO,
+            final GroupDAO groupDAO,
+            final AnyObjectDAO anyObjectDAO,
+            final RealmDAO realmDAO,
+            final PlainSchemaDAO plainSchemaDAO,
+            final AnyUtilsFactory anyUtilsFactory) {
+
+        this.userDAO = userDAO;
+        this.groupDAO = groupDAO;
... 15149 lines suppressed ...