자바 동적 에이전트 분석
동적 대 리 는 바이트 코드 강화 기술 로 서 SpringAOP 의 핵심 으로 이 루어 집 니 다.우 리 는 이 를 사용 하 는 동시에'그 이 유 를 알 고 그 이 유 를 아 는 것'을 잘 하 는 것 이 좋 습 니 다.
동적 에이전트 demo대리 류
총화
1.동적 에이전트 데모
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/** * author : * date : 16/4/20. * describe : */
public class MyInvokeHandler implements InvocationHandler {
private Object target;
public MyInvokeHandler(Object target){
super();
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before");
Object o = method.invoke(target,args);
System.out.println("after");
return o;
}
/*** * * @return * newProxyInstance , , , 。 */
public Object getProxy(){
return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),target.getClass().getInterfaces(),this);
}
}
public interface Service {
public String info();
}
public class MyService implements Service {
@Override
public String info() {
return "hello";
}
public static void main(String[] args) {
MyInvokeHandler handler = new MyInvokeHandler(new MyService());
Service service = (Service)handler.getProxy();
//
byte[] clazz = ProxyGenerator.generateProxyClass("$Proxy1",MyService.class.getInterfaces());
FileOutputStream out = null;
try {
out = new FileOutputStream("/Users/admin/Desktop/$Proxy1.class");
out.write(clazz);
out.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
service.info();
}
}
실행 결과:
before
after
이상 의 작은 demo 를 통 해 알 수 있 듯 이 동적 에이전트 의 최종 실현 효 과 는 대리 의 실행 과정 전후 에 일부 처리 논 리 를 추가 할 수 있 습 니 다.예 를 들 어 demo 에서 일부 문자열 을 인쇄 한 것 과 같 습 니 다.물론 동적 에이전트 의 기능 은 크게 다 릅 니 다.우 리 는 호출 전후 로 그 를 인쇄 하고 사 무 를 제어 하 며 강화 방법 등 을 사용 하여 소스 코드 를 수정 하지 않 은 상태 에서 우리 가 필요 로 하 는 기능 을 추가 할 수 있 습 니 다.
위의 demo 는 동적 대 리 를 어떻게 사용 하 는 지 간단하게 소개 했다.생 성 된 대리 류 의 내용 이 무엇 인지 살 펴 보 자.
2.프 록 시 클래스
같은 인터페이스 에 있어 서 현 류 는 대리 류 와 관련 이 있다.우 리 는 위 에서 프 록 시 클래스 의 바이트 코드 를 파일 에 기 록 했 습 니 다.여러분 은 역 컴 파일 한 후에 그 내용 을 다음 과 같이 볼 수 있 습 니 다.
// extends , Proxy, java
public final class $Proxy1 extends Proxy implements Service {
//4 Method 4 。
private static Method m1;
private static Method m3;
private static Method m2;
private static Method m0;
public $Proxy1(InvocationHandler paramInvocationHandler)
throws
{
super(paramInvocationHandler);
}
public final boolean equals(Object paramObject)
throws
{
try
{
return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
// , InvocationHandler invoke 。 invoke 。
public final String info()
throws
{
try
{
return (String)this.h.invoke(this, m3, null);
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
public final String toString()
throws
{
try
{
return (String)this.h.invoke(this, m2, null);
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
public final int hashCode()
throws
{
try
{
return ((Integer)this.h.invoke(this, m0, null)).intValue();
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
static
{
try
{
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
m3 = Class.forName("com.service.util.property.Service").getMethod("info", new Class[0]);
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
return;
}
catch (NoSuchMethodException localNoSuchMethodException)
{
throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
}
catch (ClassNotFoundException localClassNotFoundException)
{
throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
}
}
}
3.총화
1.동적 대 리 는 jvm 이 실 행 된 후에 메모리 에 class 를 생 성하 여 원래 가지 고 있 지 않 은 기능 을 강화 하 는 데 사용 되 지만 원래 의 클래스 도 없어 서 는 안 되 거나 없어 서 는 안 된다.왜냐하면 진정한 핵심 논 리 는 원래 의 클래스 에 있 기 때문이다.2.프 록 시 클래스 가 메모리 에 존재 하 는 방식 은 기본적으로 프 록 시 를 계승 하 는 동시에 우리 가 들 어 오 는 인 터 페 이 스 를 실현 합 니 다.실행 할 때 동적 으로 생 성 된 대상 이 고 이름 을 짓 는 방식 은 모두 이러한 형식 입 니 다.$로 시작 하고 프 록 시 를 중심 으로 마지막 숫자 는 대상 의 레이 블 을 표시 합 니 다.3.프 록 시 클래스 는 기본적으로 hashCode(),equals(),toString(),그리고 계승 하 는 인터페이스 에 필요 한 방법 을 실현 하기 때문에 proxy.getClass().getName()과 유사 한 프 록 시 클래스 의 클래스 를 호출 할 때 프 록 시 클래스 의 클래스 이름 을 얻 지 못 합 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.