Spring を使った簡易プラグイン機構としては、以下に書かれている通りでとても簡単に実現できる。
DIコンテナで実現する簡易プラグイン機構
https://blog.ik.am/entries/331
ここでは、更にプラグインの適用順序も考慮してみる。
やり方はとても簡単で @Priority
を付けて順番を定義するだけ。
MyPlugin.java
public interface MyPlugin {
String execute();
}
MyPluginService.java
@Service
public class MyPluginService {
@Autowired
List<MyPlugin> plugins;
public List<String> execute() {
return plugins.stream().map(p -> p.execute()).collect(Collectors.toList());
}
}
PluginController.java
@RestController
public class PluginController {
@Autowired
MyPluginService myPluginService;
@GetMapping("plugins")
public List<String> plugins() {
return myPluginService.execute();
}
}
@Component
@Priority(10)
public class Fuga1Plugin implements MyPlugin {
@Override
public String execute() {
return "Fuga1Plugin";
}
}
@Component
@Priority(50)
public class Hoge1Plugin implements MyPlugin {
@Override
public String execute() {
return "Hoge1Plugin";
}
}
@Component
@Priority(100)
public class Fuga2Plugin implements MyPlugin {
@Override
public String execute() {
return "Fuga2Plugin";
}
}
@Component
@Priority(200)
public class Hoge2Plugin implements MyPlugin {
@Override
public String execute() {
return "Hoge2Plugin";
}
}
実行結果
$ curl http://localhost:8080/plugins | jq .
[
"Fuga1Plugin",
"Hoge1Plugin",
"Fuga2Plugin",
"Hoge2Plugin"
]
ちなみに、Spring 4.1 からは @Order
ではなく @Priority
推奨とのこと。
また、@Conditional
を使えば、適用条件も書けたりするが、あまり使う機会はなさそう。