동적 실시 간 추적 자바 프로그램
public void say(String words){
Trace.enter();
System.out.println(words);
Trace.exit();
}
예 를 들 어 Trace. enter () 와 Trace. exit () 는 say (words) 안의 코드 를 둘러싸 고 방법 을 출입 하 는 것 을 단면 적 으로 처리 하면 운행 시의 문맥 을 얻 을 수 있 습 니 다. 예 를 들 어: interface Person {
void say(String words);
}
class Officer implements Person {
public void say(String words) { lie(words); }
private void lie(String words) {...}
}
class Proxy implements Person {
private final Officer officer;
public Proxy(Officer officer) { this.officer = officer; }
public void say(String words) {
enter();
officer.say(words);
exit();
}
private void enter() { ... }
private void exit() { ... }
}
Person p = new Proxy(new Officer());
상기 enter () 와 exit () 는 절단면 을 실현 하 는 곳 입 니 다.Officer 의 Proxy 인 스 턴 스 를 가 져 오 면 Officer 인 스 턴 스 의 행 위 를 추적 할 수 있 습 니 다. 이런 방식 은 가장 간단 하고 직접적 입 니 다. Java Proxy Java Proxy 는 JDK 에 내 장 된 프 록 시 API 로 반사 체 제 를 통 해 이 루어 집 니 다. 이 를 사용 하면 절단면 을 완성 하 는 것 은 다음 과 같 습 니 다. class ProxyInvocationHandler implements InvocationHandler {
private final Object target;
public ProxyInvocationHandler(Object target) { this.target = target;}
public Object handle(Object proxy, Method method, Object[] args) {
enter();
method.invoke(target, args);
exit();
}
private void enter() { ... }
private void exit() { ... }
}
ClassLoader loader = ...
Class<?>[] interfaces = {Person.class};
Person p = (Person)Proxy.newInstance(loader, interfaces, new ProxyInvocationHandler(new Officer()));
이전 방법 과 비교 하면 읽 기 쉽 지 않 지만 더욱 통용 되 지만,구체 적 인 구현 에 대한 의존 도가 매우 적 습 니 다. AspectJ AspectJ 3 는 바이트 코드 를 기반 으로 하 는 AOP 구현 입 니 다. 자바 proxy 에 비해 호출 이 더욱 투명 하고 간단명료 하 며 (DSL 과 유사) 성능 이 좋 습 니 다. 다음 코드: pointcut say(): execute(* say(..))
before(): say() { ... }
after() : say() { ... }
Aspectj 가 절단면 을 실현 하 는 시 기 는 두 가지 가 있 습 니 다. 정적 컴 파일 과 클래스 로드 기간 짜 임 (load - time weaving) 입 니 다.또한 IDE 에 대한 지원 이 풍부 합 니 다. CGlib 는 AspectJ 와 마찬가지 로 CGlib 4 도 바이트 코드 를 조작 하여 AOP 를 실현 합 니 다. 사용 상 자바 Proxy 와 매우 비슷 합 니 다. 다만 자바 Proxy 가 인터페이스 에 의존 하지 않 습 니 다. 우리 가 잘 알 고 있 는 Spring, Guice 와 같은 IoC 용기 가 AOP 를 실현 하 는 것 은 모두 이 를 사용 하여 이 루어 집 니 다. class Callback implements MethodInterceptor {
public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args, MethodProxy proxy) throws Throwable {
enter();
proxy.invokeSuper(obj, args);
exit();
}
private void enter() { ... }
private void exit() { ... }
}
Enhancer e = new Enhancer();
e.setSuperclass(Officer.class);
e.setCallback(new Callback());
Person p = e.create();
바이트 코드 를 조작 하 는 네 가지 방법 은 각각 적용 되 는 장면 이 있 습 니 다.그러나 실행 중인 자바 프로 세 스 만 동적 추적 을 지원 할 수 없습니다. 물론 제 가 깊이 이해 하지 못 했 을 수도 있 습 니 다. 상기 방안 을 바탕 으로 하 는 방법 이 있 으 면 아낌없이 가르쳐 주 십시오. 아니면 Btrace 5 의 사고 로 돌아 가 자바. lang. Instrumentation 을 통 해 바이트 코드 를 주입 하 는 실현 원 리 를 이해 한 후에동적 변화 추적 방식 이나 목 표를 실현 하 는 데 문제 가 없 을 것 입 니 다. 빌 린 문제, 바이트 코드 를 어떻게 조작 (주입) 하여 절단면 처 리 를 실현 하 는 지 기 쁩 니 다. 기 쁜 것 은 '자신의 모니터링 도 구 를 구축 하 는 것' 7 문 이 저 에 게 좋 은 착안점 을 제공 해 주 었 습 니 다. 이 를 바탕 으로 ASM 8 에 대한 심도 있 는 연 구 를 통 해 실현 할 수 있 습 니 다. private static class ProbeMethodAdapter extends AdviceAdapter {
protected ProbeMethodAdapter(MethodVisitor mv, int access, String name, String desc, String className) {
super(mv, access, name, desc);
start = new Label();
end = new Label();
methodName = name;
this.className = className;
}
@Override
public void visitMaxs(int maxStack, int maxLocals) {
mark(end);
catchException(start, end, Type.getType(Throwable.class));
dup();
push(className);
push(methodName);
push(methodDesc);
loadThis();
invokeStatic(Probe.TYPE, Probe.EXIT);
visitInsn(ATHROW);
super.visitMaxs(maxStack, maxLocals);
}
@Override
protected void onMethodEnter() {
push(className);
push(methodName);
push(methodDesc);
loadThis();
loadArgArray();
invokeStatic(Probe.TYPE, Probe.ENTRY);
mark(start);
}
@Override
protected void onMethodExit(int opcode) {
if (opcode == ATHROW) return; // do nothing, @see visitMax
prepareResultBy(opcode);
push(className);
push(methodName);
push(methodDesc);
loadThis();
invokeStatic(Probe.TYPE, Probe.EXIT);
}
private void prepareResultBy(int opcode) {
if (opcode == RETURN) { // void
push((Type) null);
} else if (opcode == ARETURN) { // object
dup();
} else {
if (opcode == LRETURN || opcode == DRETURN) { // long or double
dup2();
} else {
dup();
}
box(Type.getReturnType(methodDesc));
}
}
private final String className;
private final String methodName;
private final Label start;
private final Label end;
}
더 많은 참고 사항 은 여기 를 보십시오 Demo , 이것 은 javaagent 입 니 다. 숙주 프로 세 스 가 시 작 된 후에 MBean 은 jconsole 로 동적 추적 관 리 를 할 수 있 습 니 다. 후속 방향 입 니 다.이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Why does there exist DB_UNKNOWN directory on ASM disk?Today I found a glitch about my database instance.When I browsed my files on ASM disks,I found this file,which path was ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.