反射在工作中的应用
1.1 反射基础
1.1.1 获取Class的三种方式
1.1.1.1 完全限定名
Class aClass1 = Class.forName("com.mydemo.domain.ReflectDomain");
1.1.1.2 对象.getClass()
ReflectDomain domain = new ReflectDomain();
Class<? extends ReflectDomain> aClass = domain.getClass();
1.1.1.3 类.class
Class<ReflectDomain> domain = ReflectDomain.class;
1.1.2 属性相关方法
方法 | 描述 |
---|---|
getField(String name) | 获取某个public属性 |
getFields() | 获取所有public属性 |
getDeclaredField(String name) | 无视修饰符,获取某个属性 |
getDeclaredFields() | 无视修饰符,获取所有属性 |
// 设置属性 obj 要set的对象 value 要set的值 Field对象 要set的属性
Field对象.set(Object obj, Object value)
// 获取属性 obj 要读取属性的对象
Field对象.get(Object obj)
1.1.3 方法相关方法
方法 | 描述 |
---|---|
getMethod(String name, Class<?>… parameterTypes) | 获取某个public方法 |
getMethods() | 获取所有public方法 |
getDeclaredMethod(String name, Class<?>… parameterTypes) | 无视修饰符,获取某个方法 |
getDeclaredMethods() | 无视修饰符,获取所有方法 |
// 执行方法 obj 执行方法的对象。args方法参数 Method对象 要执行的方法
Method对象.invoke(Object obj, Object... args)
1.1.4 构造器相关方法
方法 | 描述 |
---|---|
getConstructor(Class<?>… parameterTypes) | 获取与参数类型匹配的public构造方法 |
getConstructors() | 获取所有public构造方法 |
getDeclaredConstructor(Class<?>… parameterTypes) | 无视修饰符,获取与参数类型匹配的构造方法 |
getDeclaredConstructors() | 无视修饰符,获取所有构造方法 |
// 获取实例
clazz对象.newInstance()
Constructor对象.newInstance()
1.2 反射应用
在实际工作中,由于技术和人员的更新迭代,导致公司某些项目缺少jar包、或者有jar包没办法使用。
原代码:
@Configuration
public class InitializeCore {
@Value("${spring.application.name}")
public String appname;
@Value("${encryptionkey}")
public String encryptionKey;
@Value("${updateWorkWeixinContact}")
public boolean updateWorkWeixinContact;
// @Autowired
// FieldManageList fm;
@Autowired
WorkWeixinService workWeixinService;
/**
* APP初始化函数. 切记,确定了加密KEY就不要修改!
*/
@Bean
public void Initialize() {
try {
WP_CommonCore.initialize(appname, encryptionKey);
MessageDefine.initialize();
} catch (Exception e) {
e.printStackTrace();
}
}
}
可以看出是对程序某些需要的参数进行虚拟化。
但是WP_CommonCore.initialize(appname, encryptionKey);
方法执行时报错、缺少加密文件、主机MAC地址。而加密文件一台主机一份,已经无法生成。所以程序在新主机无法运行。
WP_CommonCore文件如下:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.webpower.wp_common;
import com.webpower.wp_common.csv.WP_CSV;
import com.webpower.wp_common.csv.WP_CSVBIG;
import com.webpower.wp_common.excel.WP_Excel;
import com.webpower.wp_common.file.WP_FileManager;
import com.webpower.wp_common.log.WP_Log;
import com.webpower.wp_common.threadPool.WP_ThreadPoolManager;
import com.webpower.wp_common.utils.WP_Check;
import com.webpower.wp_common.utils.WP_Encryption;
import java.io.IOException;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
public final class WP_CommonCore {
private static String $appName = "";
private static String $encryptionKey = "";
private static String $MacroServiceID = "defaultServiceID0";
private static int $cores = 1;
private static final String KEY_DIR = "corekey.lux";
private static boolean $inited = false;
public WP_CommonCore() {
}
public static void initialize(String appName, String encryptionKey) throws Exception {
ck();
String mac = getMAC();
String coreKey = loadCoreKeyFile();
if (coreKey == null) {
WP_Log.warnSimpleMsg("Missing corekey file, Current MAC address : " + mac);
System.exit(0);
} else if (!WP_Encryption.encodeMD5(mac).equals(coreKey)) {
WP_Log.warnSimpleMsg("Wrong corekey! exitting now.");
System.exit(0);
}
$encryptionKey = "";
doInit(appName, encryptionKey);
}
private static String loadCoreKeyFile() {
String coreKey = "";
try {
byte[] rawBit = WP_FileManager.read_NIO("corekey.lux");
for(int i = 0; i < 16; ++i) {
coreKey = coreKey + WP_Encryption.hexArray[rawBit[i] >>> 4 & 15];
coreKey = coreKey + WP_Encryption.hexArray[rawBit[i] & 15];
}
} catch (IOException var3) {
coreKey = null;
} catch (Exception var4) {
WP_Log.warnSimpleMsg("Bad corekey file! exitting now.");
System.exit(0);
}
return coreKey;
}
public static void ck() {
$encryptionKey = "AronLux6666";
}
public static String getMAC() {
StringBuilder macStr = new StringBuilder();
try {
InetAddress ia = InetAddress.getLocalHost();
NetworkInterface network = NetworkInterface.getByInetAddress(ia);
byte[] mac = network.getHardwareAddress();
for(int i = 0; i < mac.length; ++i) {
macStr.append(String.format("%02X", mac[i]));
}
} catch (SocketException var5) {
var5.printStackTrace();
} catch (UnknownHostException var6) {
var6.printStackTrace();
}
return macStr.toString();
}
private static void doInit(String appName, String encryptionKey) throws Exception {
if ($appName.isEmpty()) {
if (!WP_Check.isEnglishAndNumeric(appName)) {
System.out.println("[ERROR]!! <WP_CommonUtils> Initialize error! please use English & Numeric for appName");
return;
}
if (encryptionKey.length() != 8 || !WP_Check.isEnglishAndNumeric(encryptionKey)) {
System.out.println("[ERROR]!! <WP_CommonUtils> Initialize error! please use 8 English & Numeric for encryptionKey");
return;
}
$appName = appName;
$encryptionKey = encryptionKey;
WP_Log.applicationStartLog(appName);
$cores = Runtime.getRuntime().availableProcessors();
WP_ThreadPoolManager.initialize();
$inited = true;
WP_Log.infoSimpleMsg("Started WP_CommonCore");
} else if ($appName != appName) {
System.out.println("[WARNING]!! <WP_CommonUtils> has already Initialized!");
}
}
public static String getAppName() {
return $appName;
}
public static String getEncryptionKey() {
return $encryptionKey;
}
public static String getMacroServiceID() {
return $MacroServiceID;
}
public static void setMacroServiceID(String id) {
$MacroServiceID = id;
}
public static void shutdown() {
WP_ThreadPoolManager.shutdownALL();
WP_Excel.shutdown();
WP_CSV.shutdown();
WP_CSVBIG.shutdown();
}
public static int getCPUcores() {
return $cores;
}
public static boolean isInitialized() {
return $inited;
}
}
可以发现``WP_CommonCore.initialize(appname, encryptionKey)`方法,当中
ck();
String mac = getMAC();
String coreKey = loadCoreKeyFile();
if (coreKey == null) {
WP_Log.warnSimpleMsg("Missing corekey file, Current MAC address : " + mac);
System.exit(0);
} else if (!WP_Encryption.encodeMD5(mac).equals(coreKey)) {
WP_Log.warnSimpleMsg("Wrong corekey! exitting now.");
System.exit(0);
}
$encryptionKey = "";
这部分代码是检查加密文件、主机mac地址。
也就是说,只要不执行这部分代码,直接执行doInit(appName, encryptionKey);
就可以越过检查,继续进行初始化。那么修改代码如下:
@Configuration
public class InitializeCore {
@Value("${spring.application.name}")
public String appname;
@Value("${encryptionkey}")
public String encryptionKey;
@Value("${updateWorkWeixinContact}")
public boolean updateWorkWeixinContact;
// @Autowired
// FieldManageList fm;
@Autowired
WorkWeixinService workWeixinService;
/**
* APP初始化函数. 切记,确定了加密KEY就不要修改!
*/
@Bean
public void Initialize() {
try {
Class<?> wpccClazz = Class.forName("com.webpower.wp_common.WP_CommonCore");
Object wpccObj = wpccClazz.getDeclaredConstructor().newInstance();
Method method = wpccClazz.getDeclaredMethod("doInit", String.class, String.class);
method.setAccessible(true);
// 越过公司公共包内对MAC地址加密文件的校验逻辑
method.invoke(wpccObj, appname, encryptionKey);
MessageDefine.initialize();
} catch (Exception e) {
e.printStackTrace();
}
}
}