PF4J-Spring

repository·master·Indexed 19 days ago

https://github.com/pf4j/pf4j-spring

A proof of concept integration that allows PF4J extensions to be integrated into the Spring Framework ecosystem. It enables extensions to be managed and injected as Spring beans using components such as SpringPluginManager, SpringPlugin, ExtensionsInjector, and SpringExtensionFactory.

Tokens
1.4K
Snippets
4
Records
7
Agent score
15%

What's inside pf4j-spring

  1. Core Components of PF4J-Spring

    master

    PF4J-Spring provides several key components to bridge PF4J extensions with the Spring Framework:

    • SpringPluginManager: A PluginManager that is aware of the Spring context.
    • SpringPlugin: The base class your plugin must extend if it contains Spring beans.
    • ExtensionsInjector: Responsible for exposing PF4J extensions as Spring beans.
    • SpringExtensionFactory: An ExtensionFactory used in your PluginManager to handle SpringPlugin instances. It creates a new extension instance for every request.
    • SingletonSpringExtensionFactory: An alternative to SpringExtensionFactory that returns a specific singleton instance. You can optionally specify which extension classes should be treated as singletons.
  2. Install pf4j-spring via Maven

    master

    To use PF4J-Spring in your project, add the following dependency to your pom.xml. Ensure you replace ${pf4j-spring.version} with the latest available version from Maven Central.

    <dependency>
        <groupId>org.pf4j</groupId>
        <artifactId>pf4j-spring</artifactId>
        <version>${pf4j-spring.version}</version>
    </dependency>
  3. Implement a Spring-aware Plugin using SpringPlugin

    master

    To create a plugin that uses the Spring Framework internally (e.g., to manage its own beans), extend SpringPlugin. You must override createApplicationContext() to initialize a Spring ApplicationContext using the plugin's specific ClassLoader.

    public class HelloPlugin extends SpringPlugin {
    
        public HelloPlugin(PluginWrapper wrapper) {
            super(wrapper);
        }
    
        @Override
        public void start() {
            System.out.println("HelloPlugin.start()");
        }
    
        @Override
        public void stop() {
            System.out.println("HelloPlugin.stop()");
            super.stop(); // to close applicationContext
        }
    
        @Override
        protected ApplicationContext createApplicationContext() {
            AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
            applicationContext.setClassLoader(getWrapper().getPluginClassLoader());
            applicationContext.register(SpringConfiguration.class);
            applicationContext.refresh();
    
            return applicationContext;
        }
    
        @Extension
        public static class HelloGreeting implements Greeting {
    
            @Autowired
            private MessageProvider messageProvider;
    
            @Override
            public String getGreeting() {
               return messageProvider.getMessage();
            }
        }
    }
  4. Use Maven Snapshots for pf4j-spring

    master

    If you need to use the latest SNAPSHOT version, add the Sonatype Maven Repository to your pom.xml:

    <repositories>
        <repository>
            <id>sonatype-nexus-snapshots</id>
            <url>https://oss.sonatype.org/content/repositories/snapshots</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>
  5. Consume PF4J extensions as Spring beans

    master

    Once configured, you can automatically inject PF4J extensions into your Spring components using @Autowired. This allows you to treat plugin extensions as standard Spring-managed beans.

    public class Greetings {
    
        @Autowired
        private List<Greeting> greetings;
    
        public void printGreetings() {
            System.out.println(String.format("Found %d extensions for extension point '%s'", greetings.size(), Greeting.class.getName()));
            for (Greeting greeting : greetings) {
                System.out.println(">>> " + greeting.getGreeting());
            }
        }
    }
  6. How ExtensionsInjector names Spring beans

    master
    The ExtensionsInjector registers each PF4J extension as a bean in the Spring context. The bean name is the fully qualified name of the extension class (e.g., org.pf4j.demo.welcome.WelcomePlugin$WelcomeGreeting).