Run Time Modular Spring Boot

Why Modular?

Building a modular system can shorten development times, improve code management, prolong system life span, and provide a more efficient deployment of different packaging matching a different set of users’ requirements.

Types of modularity

Compile Time Modularity

In compile-time modularity, the developer is required to declare which modules an application will use. When the required modules change or when a module is updated, the whole system must be re-built. Most developers think of compile-time modularity when modularity comes to mind.

Run-time modularity

On the other hand, a run time modular system can dynamically be deployed by simply including different modules in the deployment or adding new modules to an already running system. 

Run-time modularity is based on plugins or Micro-services.

The Benefits of Run Time Modular System based on plugins
  • Services, Domain Model definitions, and APIs are defined inside a set of physically isolated executables (jars when Spring is used.).
  • Different development teams are responsible for different plugin-sets with zero or close to zero communication among teams. 
  • A new version of a plugin-set doesn’t require tests outside of it.
  • The same system can be deployed in endless combinations of features meeting a fine granularity of customer needs without compiling dozens of combinations while maintaining multiple branches one would be required without a good plugin technology.
  • Extensibility takes a completely new level where changes and new versions of an extended plugin can be automatically used by extending plugins even without recompilation.
  • Unlike the Micro-services pattern, maintaining the dependencies uni-directional is easy, the never fully solved issue of database splitting in Microservices is not present as well as performance hits serialization, deserialization and communications may hit a micros-services based system.

Current modularity patterns.

Most modular systems including Spring’s own multi-modules one are of a compile-time type. That is, dependencies must be declared before a system is compiled, and a new combination of services requires a new build process preceded by dependencies declarations. This is normally followed by a full set of testing cycles for all of the system components.

A Maven-based project also uses the compile-time paradigm where all dependencies must be known before compilation.

Micro-Services are clearly of the run-time type, however, topology decisions on Micro-Service are tough, read https://dzone.com/articles/7-things-to-consider-while-moving-to-a-microservic

When using an in-process plugins system, de-coupling takes a different level even when using the same database. A service provider (in a plugin) can be extended and changed without the intervention of the development team responsible for that service and without affecting other services dependent on it.

Run Time Modularity via In-process plugins.

A run-time plugins system should support in its plugins system:

  • Dependency injection among plugins, to any depth. That is, plugins must be injectable into other plugins while the injected plugins can have other plugins injected into them. Injected plugins should have no knowledge of the plugins they are injected into.
  • The container, that is, the Spring Boot application doesn’t have to know anything about plugins extending and servicing it.
  • There should be no limitation to what a plugin/module can do in the context of Spring development, this should include REST API definitions, business services, new JPA entities, event bus support, etc.
  • In the spirit of re-use, existing plugins should be injectable into new plugins capable of extending them, this should be possible with REST services, business services, and the JPA entities model.
  • When supporting a Software As A Service (SaaS)  cloud-based system, support for multiple versions of the same plugin/module may be required.

What is Modular Development?

modular development is a software design pattern separating software components into modules each handling specific concern.

Why Build Modular Applications?

 

Modular applications are more easily maintained, have shorter development cycles, and can be packaged according to requirements.

Different Types of Modularity

Modular systems can be either for compile-time or for run time.

Run-time modular systems are much more flexible as modules can be deployed without changing other modules and with re-compilation.

Also, run time modular system, when built correctly, requires no prior knowledge or declaration of possible modules. Thus, the set of services a system provides can be altered by distributing a different set of modules. Existing systems can be extended endlessly using endless deployment combinations.

Dependencies in run time modular systems


Understanding the dependency paradigm in a modular system is crucial.

When a system can be extended without being aware of the possible services it can accommodate, a different level of productivity and flexibility can be achieved.

For example:

A Container (Spring Application) X is hosting 3 plugins A, B, C. X has no declarations of Either of A, B, and C.

Plugin C is injected into plugin D. That is, plugin D is aware of C existence and services but not vice versa.

At run time, the Container collects the plugins A, B, C, and D and injects C into D. Services and entities defined in the four plugins become available to front-end and other clients using this backend application.
When additional services are required, new plugin E can be added to the plugins repository of the system adding the required services by introducing new ones or by extending the existing ones.


 

Modular Development with FlexiCore

FlexiCore is a run-time modular system framework. 

FlexiCore implements all of the required features for a truly extensible and flexible modular system.

FlexiCore encourages and supports building solutions as sets of interconnected plug-ins, each developed using Spring Boot APIs, services, and paradigms.  Each plug-in may depend on other plug-ins.  All the components of a system are defined as plug-ins. Plug-ins have no limitations to what they define or provide, including the interfaces to front-end devices (APIs), the domain model (Database structure), and the business services.

The actual Spring boot application is FlexiCore itself, and it remains identical for any application domain without a change, pretty much like Spring itself (new versions are regularly provided). Besides providing many additional services on top of what Spring provides, FlexiCore manages the plugins and the inter-dependencies among them. This is carried out without any declaration of plugins to be used.

Special plugin support includes updating plugins remotely. This is implemented through the use of a Wizzdi provided plugin.

With FlexiCore plug-ins support, multiple versions of the same plug-in can co-reside. 

Plug-ins can declare the required version of an injected plug-in using a different version from what other plug-ins may use, front-end clients and other systems using the system API can also declare a specific version they need to use.

Deploying new or updated plugins remotely is provided.

Different users of the same back-end can access different versions of the same plugin.

Because of the no-limitations nature of the FlexiCore plugins system, a huge repository of existing plug-ins is available, free to use, and extend.  This capability alone, is a true game-changer,

Concrete examples of Modularity through plugins

Distributed System for automated shopping

 

 

Medical Device

  

IoT system servicing multiple tenants.

 

Ready to get started?