This article introduces the SPI mechanism in Spring.

Basic Practice
Spring SPI draws on the design philosophy of Java SPI. It implements the SPI mechanism through the spring.factories method, providing extensibility to the framework without modifying its source code. Specifically, we first define an SPI interface.
package com.aaron.application.SpringSpi.BasicSpiDemo;
public interface Greet {
void hello();
void bye();
}
Then we provide the following three implementation classes: CatGreet, DogGreet, PigGreet.
package com.aaron.application.SpringSpi.BasicSpiDemo;
public class CatGreet implements Greet{
@Override
public void hello() {
System.out.println("<Cat> : Hello...");
}
@Override
public void bye() {
System.out.println("<Cat> : Bye...");
}
}
package com.aaron.application.SpringSpi.BasicSpiDemo;
public class DogGreet implements Greet {
@Override
public void hello() {
System.out.println("<Dog> : Hello...");
}
@Override
public void bye() {
System.out.println("<Dog> : Bye...");
}
}
package com.aaron.application.SpringSpi.BasicSpiDemo;
public class PigGreet implements Greet {
@Override
public void hello() {
System.out.println("<Pig> : Hello...");
}
@Override
public void bye() {
System.out.println("<Pig> : Bye...");
}
}
Next, create a spring.factories file in the src/main/resources/META-INF path. Add each SPI interface along with all its implementation classes, separated by commas. For long lines, you can also use the line continuation character backslash \ to break the line. The file content is as follows:
# Syntax Specification
# <Fully qualified class name of Interface A> = <Fully qualified class name of Implementation A1>, <Fully qualified class name of Implementation A2>, <Fully qualified class name of Implementation A3>
# <Fully qualified class name of Interface B> = <Fully qualified class name of Implementation B1>, <Fully qualified class name of Implementation B2>, <Fully qualified class name of Implementation B3>
# <Fully qualified class name of Interface C> = <Fully qualified class name of Implementation C1>, <Fully qualified class name of Implementation C2>, <Fully qualified class name of Implementation C3>
com.aaron.application.SpringSpi.BasicSpiDemo.Greet = \
com.aaron.application.SpringSpi.BasicSpiDemo.PigGreet, \
com.aaron.application.SpringSpi.BasicSpiDemo.CatGreet, \
com.aaron.application.SpringSpi.BasicSpiDemo.DogGreet

Now let’s test it.
package com.aaron.application.SpringSpi.BasicSpiDemo;
import org.springframework.core.io.support.SpringFactoriesLoader;
import java.util.List;
public class SpringSpiBasicTest {
public static void main(String[] args) {
List<Greet> greetList = SpringFactoriesLoader.loadFactories(Greet.class, SpringSpiBasicTest.class.getClassLoader());
for (Greet greet : greetList) {
System.out.println("-----------------------");
greet.hello();
greet.bye();
}
}
}
The test results are as follows, which meet expectations.
