| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="utf-8"> |
| <meta name="viewport" content="width=device-width,initial-scale=1"> |
| <title>Injecting services :: Apache Isis</title> |
| <link rel="canonical" href="https://isis.apache.org/userguide/2.0.0-M6/fun/domain-entities-and-services/inject-services.html"> |
| <meta name="generator" content="Antora 2.3.4"> |
| <link rel="stylesheet" href="../../../../_/css/site.css"> |
| <link rel="stylesheet" href="../../../../_/css/site-custom.css"> |
| <link href="https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,700,700i|Raleway:300,400,500,700,800|Montserrat:300,400,700" rel="stylesheet"> |
| <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.css"/> |
| <link rel="home" href="https://isis.apache.org" title="Apache Isis"> |
| </head> |
| <body class="article"> |
| <header class="header"> |
| <nav class="navbar"> |
| <div class="navbar-brand"> |
| <a class="navbar-item" href="https://isis.apache.org"> |
| <span class="icon"> |
| <img src="../../../../_/img/isis-logo-48x48.png"></img> |
| </span> |
| <span>Apache Isis</span> |
| </a> |
| <button class="navbar-burger" data-target="topbar-nav"> |
| <span></span> |
| <span></span> |
| <span></span> |
| </button> |
| </div> |
| <div id="topbar-nav" class="navbar-menu"> |
| <a class="navbar-end"> |
| <div class="navbar-item hide-for-print"> |
| <span> |
| <input id="algolia-search-input" placeholder="Search"></span> |
| </span> |
| </div> |
| <div class="navbar-item has-dropdown is-hoverable"> |
| <a class="navbar-link" href="#">Quick Start</a> |
| <div class="navbar-dropdown"> |
| <span class="navbar-item navbar-heading">Starter Apps</span> |
| <a class="navbar-item" href="../../../../docs/2.0.0-M6/starters/helloworld.html">Hello World</a> |
| <a class="navbar-item" href="../../../../docs/2.0.0-M6/starters/simpleapp.html">Simple App</a> |
| <hr class="navbar-divider"/> |
| <span class="navbar-item navbar-heading">Demos & Tutorials</span> |
| <a class="navbar-item" href="../../../../docs/2.0.0-M6/demo/about.html">Demo App</a> |
| <a class="navbar-item" href="https://danhaywood.gitlab.io/isis-petclinic-tutorial-docs/petclinic/1.16.2/intro.html">Petclinic (tutorial)</a> |
| <hr class="navbar-divider"/> |
| <span class="navbar-item navbar-heading">Resources</span> |
| <a class="navbar-item" href="../../../../docs/2.0.0-M6/resources/cheatsheet.html">Cheatsheet</a> |
| <a class="navbar-item" href="../../../../docs/2.0.0-M6/resources/icons.html">Icons</a> |
| </div> |
| </div> |
| <div class="navbar-item has-dropdown is-hoverable"> |
| <a class="navbar-link" href="#">Guides</a> |
| <div class="navbar-dropdown"> |
| <span class="navbar-item navbar-heading">Development</span> |
| <a class="navbar-item" href="../../../../setupguide/2.0.0-M6/about.html">Setup Guide</a> |
| <hr class="navbar-divider"/> |
| <span class="navbar-item navbar-heading">Core</span> |
| <a class="navbar-item" href="../../../../userguide/2.0.0-M6/about.html">User Guide</a> |
| <a class="navbar-item" href="../../../../refguide/2.0.0-M6/about.html">Reference Guide</a> |
| <a class="navbar-item" href="../../../../testing/2.0.0-M6/about.html">Testing Guide</a> |
| </div> |
| </div> |
| <div class="navbar-item has-dropdown is-hoverable"> |
| <a class="navbar-link" href="#">Components</a> |
| <div class="navbar-dropdown"> |
| <span class="navbar-item navbar-heading">Viewers</span> |
| <a class="navbar-item" href="../../../../vw/2.0.0-M6/about.html">Web UI (Wicket)</a> |
| <a class="navbar-item" href="../../../../vro/2.0.0-M6/about.html">REST API (Restful Objects)</a> |
| <hr class="navbar-divider"/> |
| <span class="navbar-item navbar-heading">Persistence</span> |
| <a class="navbar-item" href="../../../../pjpa/2.0.0-M6/about.html">JPA (EclipseLink)</a> |
| <a class="navbar-item" href="../../../../pjdo/2.0.0-M6/about.html">JDO (DataNucleus)</a> |
| <hr class="navbar-divider"/> |
| <span class="navbar-item navbar-heading">Security</span> |
| <a class="navbar-item" href="../../../../security/2.0.0-M6/about.html">Security Guide</a> |
| <hr class="navbar-divider"/> |
| </div> |
| </div> |
| <div class="navbar-item has-dropdown is-hoverable"> |
| <a class="navbar-link" href="#">Libraries</a> |
| <div class="navbar-dropdown"> |
| <span class="navbar-item navbar-heading">For Use in Apps</span> |
| <a class="navbar-item" href="../../../../subdomains/2.0.0-M6/about.html">Subdomain Libraries</a> |
| <a class="navbar-item" href="../../../../valuetypes/2.0.0-M6/about.html">Value Type Catalog</a> |
| <hr class="navbar-divider"/> |
| <span class="navbar-item navbar-heading">Integrate between Apps</span> |
| <a class="navbar-item" href="../../../../mappings/2.0.0-M6/about.html">Bounded Context Mapping Libraries</a> |
| <hr class="navbar-divider"/> |
| <span class="navbar-item navbar-heading">Extending the framework itself</span> |
| <a class="navbar-item" href="../../../../extensions/2.0.0-M6/about.html">Extensions Catalog</a> |
| </div> |
| </div> |
| <div class="navbar-item has-dropdown is-hoverable"> |
| <a class="navbar-link" href="#">Support</a> |
| <div class="navbar-dropdown"> |
| <span class="navbar-item navbar-heading">Contact</span> |
| <a class="navbar-item" href="../../../../docs/2.0.0-M6/support/slack-channel.html">Slack</a> |
| <a class="navbar-item" href="../../../../docs/2.0.0-M6/support/mailing-list.html">Mailing Lists</a> |
| <a class="navbar-item" href="https://issues.apache.org/jira/browse/ISIS">JIRA</a> |
| <a class="navbar-item" href="https://stackoverflow.com/questions/tagged/isis">Stack Overflow</a> |
| <hr class="navbar-divider"/> |
| <span class="navbar-item navbar-heading">Releases</span> |
| <a class="navbar-item" href="../../../../docs/2.0.0-M6/downloads/how-to.html">Downloads</a> |
| <a class="navbar-item" href="../../../../relnotes/2.0.0-M6/about.html">Release Notes</a> |
| <a class="navbar-item" href="../../../../docs/2.0.0-M6/archive/1-x.html">Archive (1.x)</a> |
| <hr class="navbar-divider"/> |
| <span class="navbar-item navbar-heading">Framework</span> |
| <a class="navbar-item" href="../../../../conguide/2.0.0-M6/about.html">Contributors' Guide</a> |
| <a class="navbar-item" href="../../../../comguide/2.0.0-M6/about.html">Committers' Guide</a> |
| <a class="navbar-item" href="../../../../core/2.0.0-M6/about.html">Core Design</a> |
| </div> |
| </div> |
| <div class="navbar-item has-dropdown is-hoverable"> |
| <a class="navbar-link" href="#">ASF</a> |
| <div class="navbar-dropdown"> |
| <a class="navbar-item" href="http://www.apache.org/">Apache Homepage</a> |
| <a class="navbar-item" href="https://www.apache.org/events/current-event">Events</a> |
| <a class="navbar-item" href="https://www.apache.org/licenses/">Licenses</a> |
| <a class="navbar-item" href="https://www.apache.org/security/">Security</a> |
| <a class="navbar-item" href="https://www.apache.org/foundation/sponsorship.html">Sponsorship</a> |
| <a class="navbar-item" href="https://www.apache.org/foundation/thanks.html">Thanks</a> |
| <hr class="navbar-divider"/> |
| <a class="navbar-item" href="https://whimsy.apache.org/board/minutes/Isis.html">PMC board minutes</a> |
| </div> |
| </div> |
| <a class="navbar-item" href="../../../../docs/2.0.0-M6/about.html"> |
| <span class="icon"> |
| <img src="../../../../_/img/home.png"></img> |
| </span> |
| </a> |
| </div> |
| </div> |
| </nav> |
| </header> |
| <div class="body "> |
| <div class="nav-container" data-component="userguide" data-version="2.0.0-M6"> |
| <aside class="nav"> |
| <div class="panels"> |
| <div class="nav-panel-pagination"> |
| <a class="page-previous disabled" rel="prev" href="" title=""><span></span></a> |
| <a class="page-next disabled" rel="next" |
| href="" title=""><span></span></a> |
| <!-- |
| page.parent doesn't seem to be set... |
| <a class="page-parent disabled" rel="prev" href="" title=""><span></span></a> |
| --> |
| </div> |
| <div class="nav-panel-menu is-active" data-panel="menu"> |
| <nav class="nav-menu"> |
| <h3 class="title"><a href="../../about.html">User Guide</a></h3> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="0"> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../concepts-patterns.html">Concepts & Patterns</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../overview.html">Overview</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../domain-entities-and-services.html">Domain Entities & Services</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../object-members.html">Properties, Collections & Actions</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../ui.html">UI Layout & Hints</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../business-rules.html">Business Rules</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../drop-downs-and-defaults.html">Drop downs and Defaults</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../meta-annotations.html">Meta-annotations</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../view-models.html">View Models</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../mixins.html">Mixins</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../modules.html">Modules</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <button class="nav-item-toggle"></button> |
| <a class="nav-link" href="../../btb/about.html">Beyond the Basics</a> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../btb/i18n.html">i18n</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../btb/headless-access.html">Headless Access</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../btb/hints-and-tips.html">Hints-n-Tips</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../btb/programming-model.html">Programming Model</a> |
| </li> |
| </ul> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <button class="nav-item-toggle"></button> |
| <span class="nav-text">Extensions</span> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../command-log/about.html">Command Log</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../command-replay/about.html">Command Replay</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../flyway/about.html">Flyway</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../quartz/about.html">Quartz</a> |
| </li> |
| </ul> |
| </li> |
| </ul> |
| </li> |
| </ul> |
| </nav> |
| </div> |
| <div class="nav-panel-explore" data-panel="explore"> |
| <div class="context"> |
| <span class="title">User Guide</span> |
| <span class="version">2.0.0-M6</span> |
| </div> |
| <ul class="components"> |
| <li class="component"> |
| <span class="title"> </span> |
| <ul class="versions"> |
| <li class="version is-latest"> |
| <a href="../../../../docs/2.0.0-M6/about.html">2.0.0-M6</a> |
| </li> |
| <li class="version"> |
| <a href="../../../../docs/2.0.0-M5/about.html">2.0.0-M5</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">BC Mapping Libraries</span> |
| <ul class="versions"> |
| <li class="version is-latest"> |
| <a href="../../../../mappings/2.0.0-M6/about.html">2.0.0-M6</a> |
| </li> |
| <li class="version"> |
| <a href="../../../../mappings/2.0.0-M5/about.html">2.0.0-M5</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">Committers' Guide</span> |
| <ul class="versions"> |
| <li class="version is-latest"> |
| <a href="../../../../comguide/2.0.0-M6/about.html">2.0.0-M6</a> |
| </li> |
| <li class="version"> |
| <a href="../../../../comguide/2.0.0-M5/about.html">2.0.0-M5</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">Contributors' Guide</span> |
| <ul class="versions"> |
| <li class="version is-latest"> |
| <a href="../../../../conguide/2.0.0-M6/about.html">2.0.0-M6</a> |
| </li> |
| <li class="version"> |
| <a href="../../../../conguide/2.0.0-M5/about.html">2.0.0-M5</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">Design Docs</span> |
| <ul class="versions"> |
| <li class="version is-latest"> |
| <a href="../../../../core/2.0.0-M6/about.html">2.0.0-M6</a> |
| </li> |
| <li class="version"> |
| <a href="../../../../core/2.0.0-M5/about.html">2.0.0-M5</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">Extensions Catalog</span> |
| <ul class="versions"> |
| <li class="version is-latest"> |
| <a href="../../../../extensions/2.0.0-M6/about.html">2.0.0-M6</a> |
| </li> |
| <li class="version"> |
| <a href="../../../../extensions/2.0.0-M5/about.html">2.0.0-M5</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">Incubator Catalog</span> |
| <ul class="versions"> |
| <li class="version is-latest"> |
| <a href="../../../../incubator/2.0.0-M6/about.html">2.0.0-M6</a> |
| </li> |
| <li class="version"> |
| <a href="../../../../incubator/2.0.0-M5/about.html">2.0.0-M5</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">JDO/DataNucleus</span> |
| <ul class="versions"> |
| <li class="version is-latest"> |
| <a href="../../../../pjdo/2.0.0-M6/about.html">2.0.0-M6</a> |
| </li> |
| <li class="version"> |
| <a href="../../../../pjdo/2.0.0-M5/about.html">2.0.0-M5</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">JPA</span> |
| <ul class="versions"> |
| <li class="version is-latest"> |
| <a href="../../../../pjpa/2.0.0-M6/about.html">2.0.0-M6</a> |
| </li> |
| <li class="version"> |
| <a href="../../../../pjpa/2.0.0-M5/about.html">2.0.0-M5</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">Reference Guide</span> |
| <ul class="versions"> |
| <li class="version is-latest"> |
| <a href="../../../../refguide/2.0.0-M6/about.html">2.0.0-M6</a> |
| </li> |
| <li class="version"> |
| <a href="../../../../refguide/2.0.0-M5/about.html">2.0.0-M5</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">Release Notes</span> |
| <ul class="versions"> |
| <li class="version is-latest"> |
| <a href="../../../../relnotes/2.0.0-M6/about.html">2.0.0-M6</a> |
| </li> |
| <li class="version"> |
| <a href="../../../../relnotes/2.0.0-M5/about.html">2.0.0-M5</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">REST API (Restful Objects Viewer)</span> |
| <ul class="versions"> |
| <li class="version is-latest"> |
| <a href="../../../../vro/2.0.0-M6/about.html">2.0.0-M6</a> |
| </li> |
| <li class="version"> |
| <a href="../../../../vro/2.0.0-M5/about.html">2.0.0-M5</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">Security Guide</span> |
| <ul class="versions"> |
| <li class="version is-latest"> |
| <a href="../../../../security/2.0.0-M6/about.html">2.0.0-M6</a> |
| </li> |
| <li class="version"> |
| <a href="../../../../security/2.0.0-M5/about.html">2.0.0-M5</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">Setup Guide</span> |
| <ul class="versions"> |
| <li class="version is-latest"> |
| <a href="../../../../setupguide/2.0.0-M6/about.html">2.0.0-M6</a> |
| </li> |
| <li class="version"> |
| <a href="../../../../setupguide/2.0.0-M5/about.html">2.0.0-M5</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">Subdomains Catalog</span> |
| <ul class="versions"> |
| <li class="version is-latest"> |
| <a href="../../../../subdomains/2.0.0-M6/about.html">2.0.0-M6</a> |
| </li> |
| <li class="version"> |
| <a href="../../../../subdomains/2.0.0-M5/about.html">2.0.0-M5</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">Testing Guide</span> |
| <ul class="versions"> |
| <li class="version is-latest"> |
| <a href="../../../../testing/2.0.0-M6/about.html">2.0.0-M6</a> |
| </li> |
| <li class="version"> |
| <a href="../../../../testing/2.0.0-M5/about.html">2.0.0-M5</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">Tooling</span> |
| <ul class="versions"> |
| <li class="version is-latest"> |
| <a href="../../../../tooling/2.0.0-M6/about.html">2.0.0-M6</a> |
| </li> |
| <li class="version"> |
| <a href="../../../../tooling/2.0.0-M5/about.html">2.0.0-M5</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component is-current"> |
| <span class="title">User Guide</span> |
| <ul class="versions"> |
| <li class="version is-current is-latest"> |
| <a href="../../about.html">2.0.0-M6</a> |
| </li> |
| <li class="version"> |
| <a href="../../../2.0.0-M5/about.html">2.0.0-M5</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">Value Types Catalog</span> |
| <ul class="versions"> |
| <li class="version is-latest"> |
| <a href="../../../../valuetypes/2.0.0-M6/about.html">2.0.0-M6</a> |
| </li> |
| <li class="version"> |
| <a href="../../../../valuetypes/2.0.0-M5/about.html">2.0.0-M5</a> |
| </li> |
| </ul> |
| </li> |
| <li class="component"> |
| <span class="title">Web UI (Wicket Viewer)</span> |
| <ul class="versions"> |
| <li class="version is-latest"> |
| <a href="../../../../vw/2.0.0-M6/about.html">2.0.0-M6</a> |
| </li> |
| <li class="version"> |
| <a href="../../../../vw/2.0.0-M5/about.html">2.0.0-M5</a> |
| </li> |
| </ul> |
| </li> |
| </ul> |
| </div> |
| </div> |
| </aside> |
| </div> |
| <main role="main"> |
| <div class="toolbar" role="navigation"> |
| <button class="nav-toggle"></button> |
| <a href="../../../../docs/2.0.0-M6/about.html" class="home-link"></a> |
| <nav class="breadcrumbs" aria-label="breadcrumbs"> |
| <ul> |
| <li><a href="../../about.html">User Guide</a></li> |
| <li><a href="inject-services.html">Injecting services</a></li> |
| </ul> |
| </nav> |
| <div class="page-versions"> |
| <button class="version-menu-toggle" title="Show other versions of page">2.0.0-M6</button> |
| <div class="version-menu"> |
| <a class="version is-current" href="inject-services.html">2.0.0-M6</a> |
| <a class="version" href="../../../2.0.0-M5/fun/domain-entities-and-services/inject-services.html">2.0.0-M5</a> |
| </div> |
| </div> |
| <div class="edit-this-page"><a href="https://github.com/apache/isis/edit/2.0.0-M6/antora/components/userguide/modules/fun/pages/domain-entities-and-services/inject-services.adoc">Edit</a></div> |
| </div> |
| <article class="doc"> |
| <a name="section-top"></a> |
| <h1 class="page">Injecting services</h1> |
| <div id="preamble"> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>Apache Isis runs on top of Spring Boot, and uses Spring Boot for dependency injection, both the application’s own domain services and also the many additional services defined by the framework (such as <a href="../../../../refguide/2.0.0-M6/applib/index/services/repository/RepositoryService.html" class="page">RepositoryService</a>).</p> |
| </div> |
| <div class="paragraph"> |
| <p>Since this is a core capability of Spring, it’s worth checking out Spring’s <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-factory-collaborators">documentation</a> on the topic.</p> |
| </div> |
| <div class="admonitionblock tip"> |
| <table> |
| <tr> |
| <td class="icon"> |
| <i class="fa icon-tip" title="Tip"></i> |
| </td> |
| <td class="content"> |
| <div class="paragraph"> |
| <p>Injection is requested using the JEE <a href="https://docs.oracle.com/javaee/7/api/javax/inject/Inject.html">@javax.inject.Inject</a> annotation. |
| This is described in Spring’s documentation, <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-standard-annotations">using JSR330 standard annotations</a>.</p> |
| </div> |
| <div class="paragraph"> |
| <p>It is also possible to use Spring’s own <a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/annotation/Autowired.html">@Autowired</a> annotation. |
| Since the two annotations are effectively equivalent, we recommend using the JEE standard.</p> |
| </div> |
| </td> |
| </tr> |
| </table> |
| </div> |
| <div class="paragraph"> |
| <p>However, not only does Apache Isis use Spring to autowire domain services into other services, the framework <em>also</em> ensures that services are injected into any domain object (eg <a href="../overview.html#domain-entities" class="page">entity</a>, <a href="../overview.html#view-models" class="page">view model</a>, <a href="../overview.html#mixins" class="page">mixins</a>, <a href="../../../../testing/2.0.0-M6/fixtures/about.html#fixture-scripts" class="page">fixture script</a>, <a href="../../../../refguide/2.0.0-M6/applib/index/spec/Specification.html" class="page">specification</a> etc). |
| This is key enabler to place functionality in the "right place", eg in a domain entity/view model itself, or in a mixin.</p> |
| </div> |
| <div class="paragraph"> |
| <p>There are three ways in which to inject the domain services:</p> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p>constructor injection (further discussion in the Spring documentation, <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-constructor-injection">here</a>)</p> |
| <div class="paragraph"> |
| <p>This is recommended approach, but note that it is only supported for domain services, NOT for other domain object types.</p> |
| </div> |
| </li> |
| <li> |
| <p>setter injection (further discussion <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-setter-injection">here</a>)</p> |
| </li> |
| <li> |
| <p>field injection</p> |
| </li> |
| </ul> |
| </div> |
| <div class="paragraph"> |
| <p>Whether you use setter or field injection for domain objects etc is a matter of style. |
| Generally field injection is somewhat frowned up.</p> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="constructor-injection"><a class="anchor" href="#constructor-injection"></a>Constructor Injection.</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>As noted above, constructor injection is only available for domain services. |
| For example:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="title">CustomerRepository.java</div> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">import org.springframework.data.repository.Repository; <i class="conum" data-value="1"></i><b>(1)</b> |
| |
| @Repository |
| public class CustomerRepository { |
| private final RepositoryService repositoryService; |
| public CustomerRepository( |
| final RepositoryService repositoryService) { |
| this.repositoryService = repositoryService; |
| } |
| // ... |
| }</code></pre> |
| </div> |
| </div> |
| <div class="colist arabic"> |
| <table> |
| <tr> |
| <td><i class="conum" data-value="1"></i><b>1</b></td> |
| <td>indicates this is a repository service.</td> |
| </tr> |
| </table> |
| </div> |
| <div class="paragraph"> |
| <p>If you wish, Project Lombok can be used to remove some of the boilerplate:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="title">CustomerRepository.java</div> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">import org.springframework.stereotype.Repository; |
| import lombok.RequiredArgsConstructor; |
| |
| @Repository |
| @RequiredArgsConstructor(onConstructor_ = {@Inject} ) <i class="conum" data-value="1"></i><b>(1)</b> |
| public class CustomerRepository { |
| private final RepositoryService repositoryService; |
| // ... |
| }</code></pre> |
| </div> |
| </div> |
| <div class="colist arabic"> |
| <table> |
| <tr> |
| <td><i class="conum" data-value="1"></i><b>1</b></td> |
| <td>Generates a constructor for all <code>final</code> fields.</td> |
| </tr> |
| </table> |
| </div> |
| <div class="paragraph"> |
| <p>If the layering between services is well defined, as in the above example (application <code>CustomerRepository</code> depends upon framework <code>RepositoryService</code>), then constructor injection should work out.</p> |
| </div> |
| <div class="paragraph"> |
| <p>However, Spring does not support</p> |
| </div> |
| <div class="paragraph"> |
| <p>TODO: Cyclic dependencies</p> |
| </div> |
| <div class="paragraph"> |
| <p><a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-dependency-resolution">Dependency Resolution Process</a>, ("Circular dependencies" sidebar).</p> |
| </div> |
| <div class="paragraph"> |
| <p>TODO: Provider<></p> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="setter-and-field-injection"><a class="anchor" href="#setter-and-field-injection"></a>Setter and Field Injection</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>Setter or field injection must be used all objects <em>other</em> than domain services. |
| For example, setter injection is:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">import javax.inject.Inject; |
| |
| public class Customer { |
| ... |
| OrderRepository orderRepository; |
| @Inject <i class="conum" data-value="1"></i><b>(1)</b> |
| public void setOrderRepository(orderRepository) { |
| this.orderRepository = orderRepository; |
| } |
| }</code></pre> |
| </div> |
| </div> |
| <div class="colist arabic"> |
| <table> |
| <tr> |
| <td><i class="conum" data-value="1"></i><b>1</b></td> |
| <td>The framework injects the domain service into the entity, before any further interactions with it.</td> |
| </tr> |
| </table> |
| </div> |
| <div class="paragraph"> |
| <p>It’s not necessary for the visibility to be <code>public</code>, so it should be as restrictive as possible. |
| In many cases, default visibility will work (assuming unit tests that mock the dependency are in the same package).</p> |
| </div> |
| <div class="paragraph"> |
| <p>Some of the boilerplate can be removed using Project Lombok:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">import javax.inject.Inject; |
| import lombok.Setter; |
| |
| public class Customer { |
| ... |
| @Setter(value= AccessLevel.PACKAGE, onMethod_ = {Inject.class}) <i class="conum" data-value="1"></i><b>(1)</b> |
| OrderRepository orderRepository; |
| }</code></pre> |
| </div> |
| </div> |
| <div class="colist arabic"> |
| <table> |
| <tr> |
| <td><i class="conum" data-value="1"></i><b>1</b></td> |
| <td>Generates a package-level setter, annotated with <code>@Inject</code></td> |
| </tr> |
| </table> |
| </div> |
| <div class="paragraph"> |
| <p>If you want to use field injection, then this is simply:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">import javax.inject.Inject; |
| |
| public class Customer { |
| ... |
| @Inject OrderRepository orderRepository; |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>... and live with or disable any IDE warnings relating to field injection.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Using default visibility here still allows the field to be mocked out within unit tests (if placed in the same package as the code under test).</p> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="multiple-implementations"><a class="anchor" href="#multiple-implementations"></a>Multiple Implementations</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>If there is more than one implementation of the service, then a specific implementation can be requested using either Spring’s <a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Primary.html">@Primary</a> annotation (further discussion <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-autowired-annotation-primary">here</a>) or Spring’s <a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/annotation/Qualifier.html">Qualifier</a> annotation (further discussion <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-autowired-annotation-qualifiers">here</a>).</p> |
| </div> |
| <div class="paragraph"> |
| <p>All of the domain services provided by Apache Isis' are annotated with <code>@Qualifier</code> to enable this.</p> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="injecting-lists-of-services"><a class="anchor" href="#injecting-lists-of-services"></a>Injecting Lists of Services</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>It’s also possible to inject a list of services:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">import javax.inject.Inject; |
| |
| public class DocumentService { |
| ... |
| @Inject |
| List<PaperclipFactory> paperclipFactories; |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>These will be in the order as defined by the <code>@javax.annotation.Priority</code> annotation.</p> |
| </div> |
| <div class="paragraph"> |
| <p>This pattern can be useful when implementing the <a href="https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern">chain of responsibility</a> design pattern, that is, looking for the first implementation that can handle a request.</p> |
| </div> |
| <div class="paragraph"> |
| <p>It is also useful to "broadcast" or fan out an implementation. |
| For example, the framework defines the <a href="../../../../refguide/2.0.0-M6/applib/index/services/publishing/spi/ExecutionSubscriber.html" class="page">ExecutionSubscriber</a> SPI, which is used to publish <a href="../../../../refguide/2.0.0-M6/schema/ixn.html" class="page">Interaction Execution</a>s to external systems. |
| The framework provides a simple logging implementation, which will always be called. |
| All other implementations available will also be called.</p> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="injecting-isissessionscoped-services"><a class="anchor" href="#injecting-isissessionscoped-services"></a>Injecting `IsisSessionScope`d services</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>Most domain services are application-scoped, in other words they are stateless global singletons that are shared by all concurrent requests.</p> |
| </div> |
| <div class="paragraph"> |
| <p>A small number of framework-provided services are annotated using <a href="../../../../refguide/2.0.0-M6/applib/index/annotation/InteractionScope.html" class="page">@IsisSessionScope</a>. |
| This means that they are stateful and scoped with each isis session, in other words HTTP request. |
| One such service is <a href="../../../../refguide/2.0.0-M6/applib/index/services/queryresultscache/QueryResultsCache.html" class="page">QueryResultsCache</a>, used for performance caching.</p> |
| </div> |
| <div class="paragraph"> |
| <p>These domain services must be requested using a slightly different idiom, using the <code>Provider</code> interface. |
| For example:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">import javax.inject.Inject; |
| import javax.inject.Provider; |
| |
| public class Customer { |
| ... |
| @Inject OrderRepository orderRepository; |
| @Inject Provider<QueryResultsCache> queryResultsCacheProvider; <i class="conum" data-value="1"></i><b>(1)</b> |
| |
| public List<Order> getOrders() { |
| Customer customer = this; |
| return queryResultsCacheProvider |
| .get() <i class="conum" data-value="2"></i><b>(2)</b> |
| .execute( |
| () -> orderRepository.findByCustomer(customer), |
| Customer.class, "getOrders", |
| customer) |
| ); |
| }</code></pre> |
| </div> |
| </div> |
| <div class="colist arabic"> |
| <table> |
| <tr> |
| <td><i class="conum" data-value="1"></i><b>1</b></td> |
| <td>inject a <code>Provider</code> for the service, not directly</td> |
| </tr> |
| <tr> |
| <td><i class="conum" data-value="2"></i><b>2</b></td> |
| <td>Get the cache from the provider</td> |
| </tr> |
| </table> |
| </div> |
| <div class="paragraph"> |
| <p>If you accidentally inject the service directly (without being wrapped in <code>Provider</code>), then the framework will detect this and fail-fast.</p> |
| </div> |
| </div> |
| </div> |
| </article> |
| <aside class="article-aside toc hide-for-print" role="navigation"> |
| <p class="toc-title">On this page</p> |
| <div id="article-toc"></div> |
| </aside> |
| </main> |
| </div> |
| <footer class="footer"> |
| <div class="content"> |
| <div class="copyright"> |
| <p> |
| Copyright © 2010~2021 The Apache Software Foundation, licensed under the Apache License, v2.0. |
| <br/> |
| Apache, the Apache feather logo, Apache Isis, and the Apache Isis project logo are all trademarks of The Apache Software Foundation. |
| </p> |
| </div> |
| <div class="revision"> |
| <p>Revision: 2.0.0-M6-site-build.20210826-1021</p> |
| </div> |
| </div> |
| </footer> |
| <script src="../../../../_/js/site.js"></script> |
| <script async src="../../../../_/js/vendor/highlight.js"></script> |
| <script src="../../../../_/js/vendor/jquery-3.4.1.min.js"></script> |
| <script src="../../../../_/js/vendor/jquery-ui-1.12.1.custom.widget-only.min.js"></script> |
| <script src="../../../../_/js/vendor/jquery.tocify.min.js"></script> |
| |
| <script> |
| $(function() { |
| $("#article-toc").tocify( { |
| showEffect: "slideDown", |
| hashGenerator: "pretty", |
| hideEffect: "slideUp", |
| selectors: "h2, h3", |
| scrollTo: 120, |
| smoothScroll: true, |
| theme: "jqueryui", |
| highlightOnScroll: true |
| } ); |
| }); |
| </script> |
| |
| <script src="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.js"></script> |
| <script> |
| function focusSearchInput () { document.querySelector('#algolia-search-input').focus() } |
| var search = docsearch({ |
| appId: '5ISP5TFAEN', |
| apiKey: '0fc51c28b4ad46e7318e96d4e97fab7c', |
| indexName: 'isis-apache-org', |
| inputSelector: '#algolia-search-input', |
| autocompleteOptions: { hint: false, keyboardShortcuts: ['s'] }, |
| debug: false, |
| }).autocomplete |
| search.on('autocomplete:closed', function () { search.autocomplete.setVal() }) |
| focusSearchInput() |
| window.addEventListener('load', focusSearchInput); |
| </script> |
| |
| <!-- |
| docsearch options: |
| https://docsearch.algolia.com/docs/behavior/ |
| --> |
| <!-- |
| https://www.algolia.com/doc/api-reference/api-parameters/ |
| algoliaOptions: { hitsPerPage: 6 }, |
| --> |
| </body> |
| </html> |