Backend Development 10 min read

Simplify Spring Boot Extensions with Concept Plugin 2: A Plug‑in Guide

Concept Plugin 2 introduces a lightweight, annotation‑driven plug‑in system for Spring Boot that separates core business logic from device integration code, enabling independent testing, dynamic loading, and easy configuration through a management UI, while supporting various injection patterns, nested dependencies, and Spring features.

Java Architect Essentials
Java Architect Essentials
Java Architect Essentials
Simplify Spring Boot Extensions with Concept Plugin 2: A Plug‑in Guide

Background

I previously worked at an IoT company where we needed to integrate many devices from different manufacturers. Initially, all integration code lived inside the main service, using some design patterns and a unified interface, so the coding part was manageable.

However, adding a new device or protocol required extensive testing because any code change in the service triggered a full retest, even though only a few classes changed.

I wondered if we could separate the core business from the integration code so that changes to integration plugins wouldn't require retesting the core service. A plug‑in approach would allow independent deployment and quick fixes without republishing the whole service.

Framework Introduction

Based on that idea, the

Concept Plugin 2

framework was created.

https://github.com/Linyuzai/concept/wiki/Concept-Plugin-2

Usage

1. Configure plugins in code

<code>@EnablePluginConcept
@Configuration
public class PluginConfig {
    @OnPluginExtract
    public void plugin(CustomPlugin plugin) {
        // CustomPlugin can be any interface or class defined in your business
    }
}</code>
@EnablePluginConcept

enables the plug‑in functionality; can be placed on the main application class.

@OnPluginExtract

marks a method to receive plug‑in callbacks; the method must be discoverable by Spring.

2. Upload plugins via the management page

Plugin management UI
Plugin management UI

Management page URL:

/concept-plugin/management.html

3. No third step – the above covers everything.

Advantages

Easy to Use

Spring Boot serves as the foundation; a single annotation integrates all features, providing sensible defaults and a ready‑made management UI that anyone from testing to operations can use.

Low Learning Curve

Only two new annotations (

@EnablePluginConcept

and

@OnPluginExtract

) are needed. The rest follows standard Spring conventions, so developers can start quickly.

<code>@EnablePluginConcept
@Configuration
public class PluginConfig {
    @OnPluginExtract
    public void plugin(CustomPlugin plugin) {
        // implementation
    }
}</code>

Free Writing Style

You can define plug‑in methods with any signature you need, such as receiving a class, a list, a set, an array, or even a

Properties

object:

<code>@EnablePluginConcept
@Configuration
public class PluginConfig {
    @OnPluginExtract
    public void plugin(Class<? extends CustomPlugin> plugin) { }

    @OnPluginExtract
    public void pluginList(List<CustomPlugin> plugins) { }

    @OnPluginExtract
    public void pluginSet(Set<CustomPlugin> plugins) { }

    @OnPluginExtract
    public void pluginArray(CustomPlugin[] plugins) { }

    @OnPluginExtract
    public void plugin(CustomPlugin plugin, Properties properties) { }
}</code>

Precise Matching

If a plug‑in package contains multiple

Properties

files, you can target them individually with

@PluginEntry

using Ant‑style patterns:

<code>@EnablePluginConcept
@Configuration
public class PluginConfig {
    @OnPluginExtract
    public void plugin(@PluginEntry("first.properties") Properties p1,
                       @PluginEntry("second.properties") Properties p2) { }
}</code>

Spring Support

The framework integrates with Spring’s configuration binding, allowing you to place a

plugin.properties

file in

resources

or at the root of the zip package. Example configuration:

<code>#custom configuration
custom.app=${spring.application.name}
custom.value=custom</code>

During plug‑in execution you can read these values via

PluginMetadata

:

<code>@EnablePluginConcept
@Configuration
public class PluginConfig {
    @OnPluginExtract
    public void plugin(Plugin plugin) {
        PluginMetadata metadata = plugin.getMetadata();
        String app = metadata.get("custom.app");
        String value = metadata.get("custom.value");
        CustomData data = metadata.bind("custom", CustomData.class);
    }
}

@Data
public static class CustomData {
    private String app;
    private String value;
}</code>

Automatic Injection

Plug‑ins can use Spring’s dependency injection directly, for example:

<code>public class SpringPlugin implements CustomPlugin, ApplicationContextAware {
    @Value("${spring.application.name}")
    private String applicationName;

    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}</code>

Nested or Dependent Dependencies

If a plug‑in needs classes that are not present in the main service, you have two options:

Package the required JARs inside the plug‑in (nested dependency).

Create a base plug‑in containing common libraries and let other plug‑ins declare a dependency on it via

plugin.properties

:

<code># Base plug‑in configuration
concept.plugin.name=common
concept.plugin.handler.enabled=false</code>
<code># Dependent plug‑in configuration
concept.plugin.dependency.names=common</code>

Visualization Page

A dedicated UI page provides plug‑in upload, download, load, unload, and other basic operations.

Conclusion

For more detailed usage, refer to the Wiki at the GitHub link above.

JavaPlugin ArchitectureSpring Bootdependency injectionModular Design
Java Architect Essentials
Written by

Java Architect Essentials

Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.