I. What is SPI
The full name of SPI is Service Provider interface, which translates to "Service Provider Interface". The basic effect is to declare an interface, and then get its implementation through the configuration, and then realize dynamic extension.
Java SPI is a JDK built-in implementation of dynamically loading extension points.
It is rarely used in general business code, but it is heavily used in underlying frameworks, including JDBC, Dubbo, Spring, Solon, slf4j, etc. The difference is that some use Java's native implementations, while some frameworks implement their own set of SPI mechanisms.
II. Spring SPI
SPI in Spring compared to the JDK native , it is more powerful , it can replace the type is not limited to interfaces / abstract classes , it can be any class , interfaces , annotations ;
Because Spring SPI is an SPI that supports substitution of annotation types, this feature is reflected in auto-assembly in Spring Boot (EnableAutoConfiguration annotation):
Spring's SPI configuration file needs to be placed in the project's META-INF, and the name of the file is , and the contents of the file is essentially a properties; such as spring-boot-autoconfigure package under the META-INF/ file, used for auto-assembly.
# Auto Configure
=\
, \
, \
, \
, \
, \
,
III. Solon SPI
Solon SPI is "coded" as opposed to the "configured" style of Java SPI and Spring SPI, which is a bit like Maven and Gradle. Solon SPI, also known as Solon Plugin SPI, is a bit like Maven and Gradle. It also requires a configuration file that declares the plugin's implementation class.
The convention plugin configuration file and requires the file name to be unique:
#It is recommended to use packages as filenames to make them easier to recognize and to avoid conflicts
META-INF/solon/{packname}.properties
Agree on the content of the plugin configuration (just the two fixed ones):
# Plugin implementation class configuration
={PluginImpl}
#Plugin optimization level configuration. Larger is prioritized, default is 0
=1
Plugin code example (equivalent, provides a lifecycle for the whole "module"). Translating the Spring SPI configuration above is:
public class SpringTranslatePlugin implements Plugin{
@Override
public void start(AppContext context) {
//When the plug-in starts...
();
();
();
();
();
();
}
@Override
public void prestop() throws Throwable {
//When the plug-in is pre-stopped(When safety stop is enabled:Stopping is performed only a few seconds after pre-stopping)
}
@Override
public void stop(){
//When the plug-in stops
}
}
Because it's "coded". So it is also possible to do more complex control processing. For example:
public class SolonDataPlugin implements Plugin {
@Override
public void start(AppContext context) {
//Registering a Cache Factory
("local", new LocalCacheFactoryImpl());
//Adding Transaction Control Support
if (().enableTransaction()) {
(, , 120);
}
//Add cache control support
if (().enableCaching()) {
("", );
(, new CacheServiceWrapConsumer());
(() -> {
if (() == false) {
(, );
}
});
(, new CachePutInterceptor(), 110);
(, new CacheRemoveInterceptor(), 110);
(, new CacheInterceptor(), 111);
}
//Automatic construction of data sources
Props props = ().getProp("");
if (() > 0) {
().onEvent(, e -> {
//be in favor of ENC() cryptograph
(props);
buildDataSource(context, props);
});
}
}
}