sbp (Spring Boot Plugin)

repository·master·Indexed 43 days ago

https://github.com/hank-cp/sbp

A plugin-oriented programming framework for Spring Boot inspired by Pf4j. It enables the transformation of monolithic Spring Boot applications into modular systems where plugins can be installed, updated, started, or stopped on the fly. Supports Spring Boot 3.x (sbp version 18+) and Spring Boot 2.x.

Tokens
9.8K
Snippets
26
Records
47
Agent score
54%

What's inside sbp

  1. Overview of sbp (Spring Boot Plugin)

    master
    sbp is a plugin-oriented design capability for Spring Boot, inspired by and built upon the Pf4j project. It allows developers to transform a monolithic Spring Boot application into a modular, plugin-based architecture. This provides a middle ground between a standard monolithic Spring Boot application and a distributed Spring Cloud architecture, enabling features like online installation, upgrading, starting, and stopping of plugins without the complexity of full microservices (e.g., service discovery, traffic control).
  2. Key features and benefits of sbp

    master

    sbp provides a lightweight, spiral expansion architecture for Spring Boot applications with the following capabilities:

    • Plugin Lifecycle Management: Supports online installation, upgrading, starting, and stopping of plugins.
    • Full-Stack Spring Boot Integration: Plugins can leverage the entire Spring Boot ecosystem, including:
      • Controllers (@Controller, @RestController)
      • RouterFunction and WebFlux
      • Static resource loading and template engines (Freemarker, Velocity, Thymeleaf)
      • Persistence middleware (Spring Data, JPA, jOOQ, MyBatis Plain SQL)
      • Spring Security and AOP
    • Development Workflow: Allows developing, debugging, and testing plugins within an independent, executable Spring Boot project.
    • Low Learning Curve: Requires only Spring Boot knowledge; no additional framework expertise is needed.
    • Configuration: Uses NO XML.
  3. Approach 2: Share a single DataSource with multiple persistence middlewares (JPA + JDBC)

    master

    You can mix JPA (Hibernate) with other tools like Jooq or Mybatis on a single DataSource, but it requires careful transaction management.

    Without JTA/XA

    If you use DataSourceTransactionManager in the app and JpaTransactionManager in the plugin, you can inject them into their respective applicationContexts. However, transactions cannot be joined across different transaction managers, meaning you lose ACID guarantees across the app/plugin boundary.

    To achieve atomic transactions across different persistence layers (e.g., JPA in a plugin and JDBC in the app), you must:

    1. Set up different XADataSource instances for JPA and other middlewares.
    2. Inject a JtaTransactionManager into every plugin applicationContext.
    3. Use SharedJtaSpringBootstrap to start the plugin.
    4. Ensure AtomikosDataSourceBean is closed when the plugin stops.
  4. Extend SBP with a custom PluginLoader

    master
    By default, SBP loads plugin resources from the file system or a single JAR file. To load plugins from other formats (e.g., a fat-jar), provide a custom implementation of the PluginLoader interface via the spring.sbp.custom-plugin-loader property. Your custom loader must have a constructor that accepts a PluginManager instance.
  5. Maintain consistent framework stacks between app and plugins

    master
    To avoid classloading issues, use the same framework stack (libraries and versions) in both the main application and the plugins as much as possible. Introducing libraries with complex dependencies (such as Spring Data JPA) exclusively in a plugin can cause problems because the plugin and the app use different classloaders, making it difficult to ensure all dependent classes are loaded by the same classloader.
  6. Approach 1: Share a single DataSource with the same persistence middleware

    master

    This is the simplest and recommended way to handle persistence in sbp. You can share a single DataSource from the main application to its plugins using sbp bean management. This provides local transaction support.

    Supported Middlewares:

    • JdbcTemplate
    • Jooq
    • Mybatis

    Note: JPA/Hibernate is not a suitable option for this specific approach because of how it manages internal state and EntityManagers.

    See SharedDataSourceSpringBootstrap for implementation details.
  7. Implement unified security control using Spring Security

    master

    The sbp framework allows you to extend security control from the main application down to individual plugins. This enables the entire application to run under a unified security policy.

    Because security requirements vary by use case, sbp does not provide a one-size-fits-all security implementation. Instead, it provides the infrastructure to integrate your own Spring Security configuration. A reference implementation can be found in the demo-security project.

  8. Avoid package name conflicts with core libraries

    master
    When naming your plugin packages, ensure they do not start with org.pf4j, java, or javax. The PluginClassLoader treats these prefixes differently, which can lead to unexpected behavior. Additionally, always ensure your application package and plugin packages have distinct names to prevent the Spring context building process from failing.
  9. How to integrate third-party frameworks using IPluginConfigurer

    master

    To use Spring Boot frameworks or libraries (like JPA, Quartz, etc.) within a plugin environment, you must make them dynamically registerable/unregisterable. This is achieved by extending IPluginConfigurer.

    Configurers are invoked during the plugin's ApplicationContext bootstrap process, allowing you to register or unregister plugin resources within the main ApplicationContext.

    public class LibraryPlugin extends SpringBootPlugin {
    
        public LibraryPlugin(PluginWrapper wrapper) {
          super(wrapper, 
            // SbpWebConfigurer is mandatory, so it will be config automatically.        
            new SbpJpaConfigurer(new String[] {"demo.sbp.library.model"}),
            new SbpSpringDocConfigurer()
          );
        }
    }
  10. Deployment principles for SBP plugins

    master

    When deploying a plugin for SBP, the packaging format depends on whether your plugin has 3rd-party dependencies:

    1. No 3rd-party dependencies: A normal JAR is sufficient. However, you must sign the JAR manifest with the required plugin attributes.
    2. With 3rd-party dependencies: The "Fat-jar" format (a JAR inside a JAR, such as a standard Spring Boot executable JAR) is not supported. You must use one of two workarounds:
      • Flat lib jar: Extract all classes and resources from your dependency JARs and pack them into a single, flat JAR file alongside your plugin classes.
      • Zip format: Use the PF4J zip format. Place all 3rd-party dependency JARs under a /lib directory and your plugin classes under a /classes directory, then package everything into a .zip file.
  11. How sbp bootstraps plugin ApplicationContexts

    master

    The sbp project extends the standard SpringApplication via a class called SpringBootstrap. This allows the system to bootstrap a dedicated plugin ApplicationContext alongside the main application context.

    Note on Classloading: While sbp is based on pf4j, it implements a custom rewritten classloading behavior that differs significantly from the original pf4j implementation.

  12. Understand the demo project structure and modules

    master

    The demo project is organized into several modules that demonstrate different sbp capabilities:

    Core Modules

    • demo-shared: Contains shared code used by both application and plugin projects.
    • demo-security: Demonstrates how to introduce Spring Security and secure APIs via AOP.
    • demo-apis: Contains classes that must be declared as APIs to be shared between apps and plugins, or between different plugins.
    • demo-app: The master project and entry point. It contains the two Spring Boot applications (DemoApp and DemoSecurityApp) and the following plugins:
      • demo-plugin-admin: Demonstrates Spring Security integration within a plugin and support for Spring Boot profiles.
      • demo-plugin-author: Demonstrates sharing resources (e.g., DataSource, TransactionManager) between APIs and plugins.
      • demo-plugin-library: Demonstrates usage of Spring Data/JPA.
      • demo-plugin-shelf: Demonstrates API exposure and invocation between different plugins.

    Specialized Starters

    • demo-jpa: Demonstrates using Spring Data/JPA via the sbp-spring-boot-jpa-starter.
    • demo-webflux: Demonstrates using Spring WebFlux via the sbp-spring-boot-webflux-starter.