实现思路
- 定义接口:首先定义一个所有插件模块都要实现的接口,这是多态性的基础。
- 创建插件模块:每个插件模块实现上述定义的接口。
- 配置文件:使用配置文件(如properties文件)来记录插件类的全限定名,便于动态加载。
- 反射加载:利用Java的反射机制,通过读取配置文件中的类名,在运行时动态加载插件类,并创建实例。
- 多态使用:将创建的实例当作接口类型使用,从而体现接口的多态性。
代码示例
- 定义接口
public interface Plugin {
void execute();
}
- 创建插件模块
public class PluginOne implements Plugin {
@Override
public void execute() {
System.out.println("PluginOne is executing.");
}
}
public class PluginTwo implements Plugin {
@Override
public void execute() {
System.out.println("PluginTwo is executing.");
}
}
- 配置文件(plugins.properties)
plugin1=com.example.PluginOne
plugin2=com.example.PluginTwo
- 反射加载与多态使用
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class PluginLoader {
public static void main(String[] args) {
Properties props = new Properties();
try (InputStream inputStream = PluginLoader.class.getClassLoader().getResourceAsStream("plugins.properties")) {
props.load(inputStream);
for (String key : props.stringPropertyNames()) {
String className = props.getProperty(key);
try {
Class<?> pluginClass = Class.forName(className);
Plugin plugin = (Plugin) pluginClass.getDeclaredConstructor().newInstance();
plugin.execute();
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
代码说明
- 接口定义:
Plugin
接口定义了所有插件模块需要实现的方法execute
,这是多态性的基础,不同的插件模块可以有不同的实现。
- 插件模块:
PluginOne
和PluginTwo
是两个具体的插件模块,它们实现了Plugin
接口,并提供了各自的execute
方法实现。
- 配置文件:
plugins.properties
文件记录了插件类的全限定名,这样在运行时可以通过读取配置文件来获取需要加载的插件类。
- 反射加载与多态使用:
PluginLoader
类中的main
方法首先读取plugins.properties
文件。
- 然后通过
Class.forName(className)
反射加载每个插件类,并通过getDeclaredConstructor().newInstance()
创建实例。
- 由于实例被强制转换为
Plugin
接口类型,所以在调用execute
方法时,体现了接口的多态性,即根据实际的插件类执行不同的execute
逻辑。