1、unix c
通过将源代码编译编译成so动态库,dlopen实现动态加载so库中函数(一般通过配置实现 交易码+so库名+函数名称),并通过对应的函数指针实现dlsym调用后地址转换。
1:创建test.h, test.c文件
//test.h
#ifndef TEST_H_
#define TEST_H_
#include <stdio.h>
void PrintHello();
int Add(int a, int b);
#endif
2:将其编译成动态库
gcc test.c -shared -fPIC -o libtest.so
3:创建主文件main.c
//main.c
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <signal.h>
#include <errno.h>
//输出错误信息并退出
void error_quit(const char *str)
{
fprintf(stderr, "%s\n", str);
exit(1);
}
int main(int argc, char *argv [])
{
void *plib; //指向so文件的指针
typedef void (*FUN_HELLO)();
typedef int (*FUN_ADD)(int, int);
FUN_HELLO funHello = NULL; //函数指针
FUN_ADD funAdd = NULL;
//打开so文件
//为了方便演示,我将库文件和可执行文件放在同一个目录下
plib = dlopen("./libtest.so", RTLD_NOW | RTLD_GLOBAL);
if( NULL == plib )
error_quit("Can't open the libtest.so");
//加载函数void Hello()
funHello = dlsym(plib, "Hello");
if( NULL == funHello )
error_quit("Can't load function 'Hello'");
//加载函数int Add(int a, int b)
funAdd = dlsym(plib, "Add");
if( NULL == funAdd )
error_quit("Can't load function 'Add'");
//调用成功加载的函数
funHello();
printf("5 + 8 = %d\n", funAdd(5, 8));
//关闭so文件
dlclose(plib);
return 0;
}
4:编译,运行
gcc main.c -o main -ldl
./main
2、java语言通过类Class实现对配置文件中指定的全路径类加载
student类:
public class Student {
public void show(){
System.out.println("is show()");
}
}
配置文件以txt文件为例子(pro.txt):
className = cn.fanshe.Student
methodName = show
测试类:
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Properties;
/*
* 我们利用反射和配置文件,可以使:应用程序更新时,对源码无需进行任何修改
* 我们只需要将新类发送给客户端,并修改配置文件即可
*/
public class Demo {
public static void main(String[] args) throws Exception {
//通过反射获取Class对象
Class stuClass = Class.forName(getValue("className"));//"cn.fanshe.Student"
//2获取show()方法
Method m = stuClass.getMethod(getValue("methodName"));//show
//3.调用show()方法
m.invoke(stuClass.getConstructor().newInstance());
}
//此方法接收一个key,在配置文件中获取相应的value
public static String getValue(String key) throws IOException{
Properties pro = new Properties();//获取配置文件的对象
FileReader in = new FileReader("pro.txt");//获取输入流
pro.load(in);//将流加载到配置文件对象中
in.close();
return pro.getProperty(key);//返回根据key获取的value值
}
}
总结:
将上面的代码加以扩展可实现一套交易系统的服务入口配置化(入口函数声明时参数固定)