응용 프로그램이 커지고 모듈화 될 때 특정 프로그램 지점에서 이러한 변경사항을 적용하는 것은 제약이 많이 따릅니다.
그리고 그러한 클래스를 재정의할 때 적용 할 수있는 더 좋은 방법이 있습니다 . Javaagent 사용하면 Java 응용 프로그램 내에서 수행되는 모든 클래스 로딩 활동을 직접 가로 챌 수 있습니다. Java 에이전트는 링크 된 자원에 설명 된대로이 jar 파일의 Manifest 파일에 지정된 시작점이 있는 단순 jar 파일로 구현됩니다 . 바이트 버디를 사용하면 이러한 에이전트의 구현을 간단하게 사용할 수 있습니다.
새로운 프로젝트 생성
- 위의 코드를 참조하여 동일하게 생성
public class MasulaAgent {
public static void premain(String agentArgs, Instrumentation inst) {
new AgentBuilder.Default()
.type(ElementMatchers.any())
.transform(new AgentBuilder.Transformer() {
@Override
public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassLoader classLoader, JavaModule javaModule) {
return builder.method(named("PullOut")).intercept(FixedValue.value("Rabbit!"));
}
}).installOn(inst);
}
}
- agent를 jar로 패키징
https://maven.apache.org/plugins/maven-jar-plugin/examples/manifest-customization.html
https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<archive>
<index>true</index>
<manifest>
<addClasspath>true</addClasspath>
</manifest>
<manifestEntries>
<mode>development</mode>
<url>${project.url}</url>
<key>value</key>
<Premain-Class>me.choi.MasulaAgent</Premain-Class>
<Can-Redefine-Classes>true</Can-Redefine-Classes>
<Can-Retransform-Classes>true</Can-Retransform-Classes>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
Premain-Class, Can-Redefind-Classes, Can-Retransform-Classes 추가
Agent 패키징 실행
mvn clean package
본 프로젝트에 돌아와서 작성한 jar파일을 불러와보자
VM options에 해당 javaaagent 경로 삽입
-javaagent:/Applications/개발환경/repository/PURE_JAVA/TheJava/MasulsaAgent/target/MasulsaAgent-1.0-SNAPSHOT.jar
출력
정말 코드에 아무 짓도 하지 않았다.
public class Masulsa {
public static void main(String[] args) throws IOException {
System.out.println(new Moja().PullOut());
}
}
실행결과
바이트코드를 살펴보자
클래스 파일 자체를 변경하는 것이 아니라
클래스 로딩할 때 javaagent를 거쳐서 변경된 바이트코드를 적용된다.
Code Link
https://github.com/mike6321/PURE_JAVA/tree/master/TheJava
'Java > Java' 카테고리의 다른 글
(JAVA) 리플렉션 API(2) - 애노테이션과 리플렉션 (0) | 2019.12.22 |
---|---|
(JAVA) 리플렉션 API(1) - 클래스 정보 조회 (0) | 2019.12.22 |
(JAVA) 바이트코드 조작(2) (0) | 2019.12.22 |
(JAVA) 바이트코드 조작(1) (0) | 2019.12.22 |
(JAVA) 클래스로더 (0) | 2019.12.21 |