有个第三方工具类,不支持多例模式。但是又不能直接改第三方工具类的代码,因此可以通过反射破坏第三方工具类的单例。
第三方工具类反编译如下
可以看到构造函数进行了私有化,不允许外部new,只能通过newInstance进行实例化。并且newInstance是单例的。
DataHandler.class
public class DataHandler {
private static volatile DataHandler INSTANCE;
private final byte[] encryptKeys;
private final String publicKeys;
private final String privateKeys;
private final String appID;
private final String secret;
private String version = "2.0.0";
private boolean skipVerify = false;
private DataHandler(String appID, String secret, String publicKey, String privateKey) throws IOException {
//.....
}
public static DataHandler newInstance(String appID, String secret, String publicKey, String privateKey) throws IOException {
if (INSTANCE == null) {
Class var4 = DataHandler.class;
synchronized(DataHandler.class) {
if (INSTANCE == null) {
INSTANCE = new DataHandler(appID, secret, publicKey, privateKey);
}
}
}
return INSTANCE;
}
}
通过反射破坏单例模式
import java.lang.reflect.Constructor;
public class DataHandlerFactory {
public static DataHandler createNewInstance(String appId, String appSecret, String publicKey, String privateKey) {
try {
// 获取DataHandler类的构造函数
Constructor<DataHandler> constructor = DataHandler.class.getDeclaredConstructor(String.class, String.class, String.class, String.class);
constructor.setAccessible(true);
// 通过反射创建新的实例
return constructor.newInstance(appId, appSecret, publicKey, privateKey);
} catch (Exception e) {
return null;
}
}
}
使用方法
//原本使用第三方工具类的方式,默认单例模式
DataHandler dataHandler = DataHandler.newInstance(appId, appSecret, publicKey, privateKey);
//修改后,允许多例。createNewInstance方法如果抛出异常,那么是有可能为null,因此下面要进行手动判空
DataHandler dataHandler = DataHandlerFactory.createNewInstance(appId, appSecret, publicKey, privateKey);
if (Objects.isNull(dataHandler)) {
throw new RuntimeException("创建DataHandler对象失败,请检查appId, appSecret, publicKey, privateKey值是否正确。");
}