English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Eclipse에서 Javassist를 올바르게 사용하는 방법 코드 분석

최근 Hibernate의 프록시 부분을 본 후, 첫 번째 반응은 반영에 반영된 것이었고, 사용자 엔티티에 대해 프록시 클래스를 생성하는 반영을 사용하고 있다는 것을 알게 되었습니다. 그러나 반영은 새로운 클래스를 생성할 수 있는 능력이 없기 때문에, 그게 자연스럽게 Javassist(다운로드 주소)를 찾게 되었습니다.

인터넷에서 찾은 많은 강의들은 Javassist API에 대해 설명하는 데 중점을 두고 있지만, 결국에는 로드 과정이 없습니다. 저자가 이러한 강의를 모방하여 클래스를 로드할 때, 로드된 결과는 원래의 클래스로 돌아오며 바이너리 코드가 수정된 내용이 생성되지 않았습니다.

한동안 탐구한 후, 저자는 대부분의 인터넷 강의에서 마지막 단계로 바이너리 코드를 저장하는 과정에서 writeFile의 매개변수 없는 오버로드를 사용한다는 것을 발견했습니다. 함수 구조를 확인한 후, 그것은 또 하나의 String형 오버로드도 있다는 것을 알게 되었습니다. Eclipse에서 바이너리 코드가 저장되는 기본 위치는 ".\\"가 아니라 ".\\bin"이기 때문에, writeFile의 다른 오버로드는 바이너리 코드 기본 위치를 지정하는 매개변수일 가능성이 큽니다. 저자가 몇 가지 변경을 시도한 후, 예상했던 것과 같이 맞았습니다.

다음에 코드를 공유하겠습니다:

이 저자의 프로젝트 구조는 다음과 같습니다:

Editable.java: 
package com.thrblock.javassist; 
public class Editable {}} 
   public void showInfo(){ 
       System.out.println("InfoDefault!"); 
   } 
} 
Main.java: 
package com.thrblock.javassist;
import java.io.IOException;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.NotFoundException;
public class Main {
	public static void main(String[] args) {
		ClassPool pool = ClassPool.getDefault();
		try{}}
			pool.insertClassPath(".\\bin");
			//루트 경로를 설정합니다. (이곳에서 설정된 루트 경로는 writeFile에서 사용되지 않습니다.) 
			CtClass cc = pool.makeClass("com.thrblock.javassist.EditableChanged");
			//Hibernate 대리 모델을 모의하려면, 새 클래스를 생성합니다 
			cc.setSuperclass(pool.get("com.thrblock.javassist.Editable"));
			//부모 클래스를 설정합니다 
			CtMethod cm = CtNewMethod.make("public void showInfo(){super.showInfo();System.out.println("CustomInsertHAHA!");}",cc);
			//메서드를 추가하세요. 그것이 부모 클래스의 메서드를 덮어씁니다. 
			cc.addMethod(cm);
			cc.writeFile(".\\bin");
			//이 부분이 매우 중요합니다. 공백 파라미터의 결과는 eclipse 바이트코드 루트 경로에 저장되지 않습니다.
		}
		catch (NotFoundException | CannotCompileException | IOException e) {
			e.printStackTrace();
		}
		try{}}
			Class<?> cl = Class.forName("com.thrblock.javassist.EditableChanged");
			//우리의 새 클래스 로드 
			Editableed = (Editable) cl.newInstance();
			//Editable 클래스를 상속했기 때문에, 이것과 Hibernate에서의 load 원리가 같습니다. 
			ed.showInfo();
			//메서드 호출.
		}
		catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
			e.printStackTrace();
		}
	}
}

출력 결과:

InfoDefault!

CustomInsertHAHA!

기타 주의사항:

저희는 클래스를 생성했기 때문에, 클래스 이름이 원래 클래스 이름과 같다면 class 파일을 덮어쓸 것입니다. 그러나 JVM에 이미 해당 class가 로드되었으면, 수정된 부분은 적용되지 않으며, JVM을 재시작해야 합니다.

결론

이것이 Eclipse에서 Javassist의 올바른 사용 방법에 대한 코드 분석의 전체 내용입니다. 많은 도움이 되었기를 바랍니다. 관심이 있는 분은 이 사이트의 다른 관련 주제를 참고하시기 바랍니다. 부족한 점이 있으면, 댓글을 통해 지적해 주시기 바랍니다. 이 사이트에 대한 지지를 감사합니다!

고지사항: 이 문서의 내용은 인터넷에서 가져왔으며, 저작권은 원저자에게 있으며, 인터넷 사용자가 자발적으로 기여하고 자체적으로 업로드한 내용입니다. 이 사이트는 소유권을 가지지 않으며, 인공적으로 편집한 것도 아니며, 관련 법적 책임도 부담하지 않습니다. 저작권 위반이 의심되는 내용이 있으면, notice#w로 이메일을 보내 주시기 바랍니다.3codebox.com(보고할 때는 #을 @으로 변경하십시오.)를 통해 신고하시고 관련 증거를 제공하시면, 실제로 확인되면 이 사이트는 즉시 저작권 위반 내용을 삭제합니다.

좋아하는 것