0%

浅谈Spring SPI 机制

这里介绍Spring下的SPI机制

abstract.png

基本实践

Spring SPI借鉴了Java SPI的设计思想。其通过spring.factories方式来实现SPI机制。实现在不修改框架源码的前提下提供框架的扩展性。具体地,我们先来定义一个SPI接口

1
2
3
4
5
6
7
package com.aaron.application.SpringSpi.BasicSpiDemo;

public interface Greet {
void hello();

void bye();
}

然后提供下述3个实现类:CatGreet、DogGreet、PigGreet

1
2
3
4
5
6
7
8
9
10
11
12
13
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...");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
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...");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
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...");
}
}

然后,在src/main/resources/META-INF路径下创建spring.factories文件。按行添加各SPI接口及其下的所有实现类,多个实现类间使用逗号进行分隔;当一行较长时,还可以使用 续行符反斜杠\ 来进行换行。文件内容如下所示

1
2
3
4
5
6
7
8
9
# 语法规范
# <接口A的全限定类名> = <实现类A1的全限定类名>, <实现类A2的全限定类名>, <实现类A3的全限定类名>
# <接口B的全限定类名> = <实现类B1的全限定类名>, <实现类B2的全限定类名>, <实现类B3的全限定类名>
# <接口C的全限定类名> = <实现类C1的全限定类名>, <实现类C2的全限定类名>, <实现类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

figure 1.png

现在我们来测试下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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();
}
}
}

测试结果如下所示,符合预期

figure 2.png

请我喝杯咖啡捏~
  • 本文作者: Aaron Zhu
  • 本文链接: https://xyzghio.xyz/SpringSPI/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-ND 许可协议。转载请注明出处!

欢迎关注我的微信公众号:青灯抽丝