如何在springboot中使用自定义类加载器
如何在spring boot中使用自定义类加载器加载bean 我需要加密spring boot项目 起初我尝试使用proguard,但失败了,因为spring使用了大量注释,并且它有DI 然后我尝试使用自定义类加载器。我想先加密我的类文件,然后使用我的自定义类加载器加载加密的类文件,然后解密它 这是我的演示: 当它启动时,它会失败:如何在springboot中使用自定义类加载器,spring,spring-boot,encryption,classloader,obfuscation,Spring,Spring Boot,Encryption,Classloader,Obfuscation,如何在spring boot中使用自定义类加载器加载bean 我需要加密spring boot项目 起初我尝试使用proguard,但失败了,因为spring使用了大量注释,并且它有DI 然后我尝试使用自定义类加载器。我想先加密我的类文件,然后使用我的自定义类加载器加载加密的类文件,然后解密它 这是我的演示: 当它启动时,它会失败: ConfigServletWebServerApplicationContext : Exception encountered during context
ConfigServletWebServerApplicationContext :
Exception encountered during context initialization - cancelling refresh attempt:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'methodValidationPostProcessor' defined in class path resource
[org/springframework/boot/autoconfigure/validation/ValidationAutoConfiguration.class]:
Unsatisfied dependency expressed through method 'methodValidationPostProcessor' parameter 0;
nested exception is
org.springframework.beans.factory.CannotLoadBeanClassException:
Error loading class [com.abc.bootbycustomloader.controller.UserController]
for bean with name 'userController' defined in file
[D:\code\boot-by-custom-loader\out\production\classes\com\abc\bootbycustomloader\controller\UserController.class]: problem with class file or dependent class;
nested exception is java.lang.LinkageError: loader (instance of com/abc/bootbycustomloader/loader/MyClassLoader):
attempted duplicate class definition for name:
"com/abc/bootbycustomloader/controller/UserController"
@springboot应用程序
公共类服务器应用程序{
公共静态void main(字符串[]args){
MyResourceLoader rLoader=新的MyResourceLoader();
SpringApplication app=新建SpringApplicationBuilder().build();
app.addPrimarySources(Arrays.asList(ServerApplication.class));
应用程序setResourceLoader(rLoader);
应用程序运行(args);
}
}
@RestController
@请求映射(“/user”)
公共类用户控制器{
@请求映射(“/hello”)
公共字符串hello(){
System.out.println(“你好…”);
回复“你好”;
}
}
公共类MyResourceLoader扩展了DefaultResourceLoader{
私有类加载器cl=新的MyClassLoader();
@凌驾
公共资源getResource(字符串位置){
System.out.println(“getResource:+位置”);
返回super.getResource(位置);
}
@凌驾
公共类加载器getClassLoader(){
返回cl;
}
}
公共类MyClassLoader扩展了ClassLoader{
@凌驾
公共类loadClass(字符串名称)引发ClassNotFoundException{
if(name.equals(“com.abc.bootbycustomloader.controller.UserController”)){
//假设UserController是加密类
//我需要加载这个加密类,并解密它!
System.out.println(“!!!!!加密!!!!!!!:”+名称);
//从特殊位置加载类,模拟解密处理
String path=“D:\\\\u clz\\UserController.class”;
字节[]数据=新字节[0];
试一试{
data=Files.readAllBytes(path.get(path));
}捕获(IOE异常){
e、 printStackTrace();
}
//模拟解密处理成功,返回解密的类
类clz=defineClass(名称,数据,0,数据.length);
返回clz;
}否则{
//假设另一个类不是加密类
//照常装就行了
返回super.loadClass(名称);
}
}
}
@SpringBootApplication
public class ServerApplication {
public static void main(String[] args) {
MyResourceLoader rLoader = new MyResourceLoader();
SpringApplication app = new SpringApplicationBuilder().build();
app.addPrimarySources(Arrays.asList(ServerApplication.class));
app.setResourceLoader(rLoader);
app.run(args);
}
}
@RestController
@RequestMapping("/user")
public class UserController {
@RequestMapping("/hello")
public String hello(){
System.out.println("hello hello hello...");
return "hello";
}
}
public class MyResourceLoader extends DefaultResourceLoader {
private ClassLoader cl = new MyClassLoader();
@Override
public Resource getResource(String location) {
System.out.println("getResource: "+location);
return super.getResource(location);
}
@Override
public ClassLoader getClassLoader() {
return cl;
}
}
public class MyClassLoader extends ClassLoader {
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
if (name.equals("com.abc.bootbycustomloader.controller.UserController")) {
// assump that UserController is the encrypted class
// i need to load this encrypted class, and decrypted it!
System.out.println("!!!!!encrypted!!!!! : " + name);
// load the class from a special place, mock the decrypted processing
String path = "D:\\_clz\\UserController.class";
byte[] data = new byte[0];
try {
data = Files.readAllBytes(Paths.get(path));
} catch (IOException e) {
e.printStackTrace();
}
// mock decrypted processing success, return the decrypted class
Class<?> clz = defineClass(name, data, 0, data.length);
return clz;
} else {
// assump that other class is not encrypted class
// just load it as usual
return super.loadClass(name);
}
}
}