GH-578 - Support for nested application modules.
The ApplicationModules bootstrap now triggers the module base package detection, followed by a new, additional pass of detecting nested application module packages. Those packages are now added to the ones we create ApplicationModule instances for and also handed into the module instance creation step as exclusions to make sure that parent modules do not include code residing in sub-modules. The bootstrap of ApplicationModules now uses a dedicated ApplicationModuleSource to allow calculating a default module name relative to the application base package. Each module now operates on the Classes instance obtained from the JavaPackage instance that constitutes the module's base package but filtered by the given exclusions.
This commit is contained in:
committed by
Oliver Drotbohm
parent
b927bf1211
commit
7838204c25
@@ -1,11 +1,6 @@
|
||||
antora:
|
||||
extensions:
|
||||
- '@springio/antora-extensions/partial-build-extension'
|
||||
- require: '@springio/antora-extensions/latest-version-extension'
|
||||
- require: '@springio/antora-extensions/inject-collector-cache-config-extension'
|
||||
- '@antora/collector-extension'
|
||||
- '@antora/atlas-extension'
|
||||
- require: '@springio/antora-extensions/root-component-extension'
|
||||
- require: '@springio/antora-extensions'
|
||||
root_component_name: 'modulith'
|
||||
site:
|
||||
title: Spring Modulith
|
||||
@@ -36,4 +31,4 @@ runtime:
|
||||
format: pretty
|
||||
ui:
|
||||
bundle:
|
||||
url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.3.7/ui-bundle.zip
|
||||
url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.4.16/ui-bundle.zip
|
||||
|
||||
@@ -158,7 +158,7 @@ icon:cubes[] Example
|
||||
├─ **icon:cube[] example.order**
|
||||
| └─ icon:plus-circle[role=green] OrderManagement.java
|
||||
└─ icon:cube[] example.order.internal
|
||||
└─ icon:plus-circle[role=green] SomethingOrderInternal.java
|
||||
└─ icon:plus-circle[role=red] SomethingOrderInternal.java
|
||||
----
|
||||
|
||||
In such an arrangement, the `order` package is considered an API package.
|
||||
@@ -169,8 +169,47 @@ Note how `SomethingOrderInternal` is a public type, likely because `OrderManagem
|
||||
This unfortunately means that it can also be referred to from other packages such as the `inventory` one.
|
||||
In this case, the Java compiler is not of much use to prevent these illegal references.
|
||||
|
||||
[[modules.advanced.open]]
|
||||
==== Open Application Modules
|
||||
[[modules.nested]]
|
||||
=== Nested Application Modules
|
||||
|
||||
As of version 1.3, Spring Modulith application modules can contain nested modules.
|
||||
This allows governing the internal structure in case a module contains parts to be logically separated in turn.
|
||||
To define nested application modules, explicitly annotate packages that are supposed to constitute with `@ApplicationModule`.
|
||||
|
||||
[source, subs="macros, quotes"]
|
||||
----
|
||||
icon:cubes[] Example
|
||||
└─ icon:folder[] src/main/java
|
||||
├─ icon:cube[] example
|
||||
| └─ icon:plus-circle[role=green] Application.java
|
||||
├─ icon:cube[] example.inventory
|
||||
| ├─ icon:plus-circle[role=green] InventoryManagement.java
|
||||
| └─ icon:minus-circle[role=red] SomethingInventoryInternal.java
|
||||
├─ icon:cube[] example.inventory.internal
|
||||
| └─ icon:plus-circle[role=red] SomethingInventoryInternal.java
|
||||
├─ icon:cube[] example.inventory.nested
|
||||
| ├─ icon:coffee[] package-info.java // @ApplicationModule
|
||||
| └─ icon:plus-circle[role=yellow] NestedApi.java
|
||||
├─ icon:cube[] example.inventory.nested.internal
|
||||
| └─ icon:minus-circle[role=red] NestedInternal.java
|
||||
└─ icon:cube[] example.order
|
||||
├─ icon:plus-circle[role=green] OrderManagement.java
|
||||
└─ icon:minus-circle[role=red] SomethingOrderInternal.java
|
||||
|
||||
----
|
||||
|
||||
In this example `inventory` is an application module as described xref:fundamentals.adoc#modules.simple[above].
|
||||
The `@ApplicationModule` annotation on the `nested` package caused that to become a nested application module in turn.
|
||||
In that arrangement, the following access rules apply:
|
||||
|
||||
* The code in _Nested_ is only available from _Inventory_, i.e. only any of the `SomethingInventoryInternal` types can access `NestedApi`. `NestedInternal` is only accessible from `NestedApi`.
|
||||
* Any code in the _Nested_ module can access code in parent modules, even internal.
|
||||
I.e., both `NestedApi` and `NestedInternal` can access `inventory.internal.SomethingInventoryInternal`.
|
||||
* Code from nested modules can also access exposed types by top-level application modules.
|
||||
Any code in `nested` (or any sub-packages) can access `OrderManagement`.
|
||||
|
||||
[[modules.open, modules.advanced.open]]
|
||||
=== Open Application Modules
|
||||
|
||||
The arrangement described xref:fundamentals.adoc#modules.advanced[above] are considered closed as they only expose types to other modules that are actively selected for exposure.
|
||||
When applying Spring Modulith to legacy applications, hiding all types located in nested packages from other modules might be inadequate or require marking all those packages for exposure, too.
|
||||
|
||||
Reference in New Issue
Block a user